<!DOCTYPE html>
<!-- saved from url=(0016)http://localhost -->
<html>
  <head>
    <meta charset="utf-8"/>
    <meta content="IE=edge" http-equiv="X-UA-Compatible"/>
    <title>设计模式之美2-结构型</title>
    <style>
        body{
            margin: 0;
        }
        #content-info{
            width: auto;
            margin: 0 auto;
            text-align: center;
        }
        #author-info{
            white-space: nowrap;
            text-overflow: ellipsis;
            overflow: hidden;
        }
        #title{
            text-overflow: ellipsis;
            white-space: nowrap;
            overflow: hidden;
            padding-top: 10px;
            margin-bottom: 2px;
            font-size: 34px;
            color: #505050;
        }
        .text{
            white-space:nowrap;
            text-overflow: ellipsis;
            display: inline-block;
            margin-right: 20px;
            margin-bottom: 2px;
            font-size: 20px;
            color: #8c8c8c;
        }
        #navBar{
            width: auto;
            height: auto;
            position: fixed;
            right:0;
            bottom: 0;
            background-color: #f0f3f4;
            overflow-y: auto;
            text-align: center;
        }
        #svg-container{
            width: 100%;
            overflow-x: scroll;
            min-width: 0px;
            margin: 0 10px;
        }
        #nav-thumbs{
            overflow-y: scroll;
            padding: 0 5px;
        }
        .nav-thumb{
            position: relative;
            margin: 10px auto;
        }
        .nav-thumb >p{
            text-align: center;
            font-size: 12px;
            margin: 4px 0 0 0;
        }
        .nav-thumb >div{
            position: relative;
            display: inline-block;
            border: 1px solid #c6cfd5;
        }
        .nav-thumb img{
            display: block;
        }
        #main-content{
            bottom: 0;
            left: 0;
            right: 0;
            background-color: #d0cfd8;
            display: flex;
            height: auto;
            flex-flow: row wrap;
            text-align:center;
        }
        #svg-container >svg{
            display: block;
            margin:10px auto;
            margin-bottom: 0;
        }
        #copyright{
            bottom: 0;
            left: 50%;
            margin: 5px auto;
            font-size: 16px;
            color: #515151;
        }
        #copyright >a{
            text-decoration: none;
            color: #77C;
        }
        .number{
            position: absolute;
            top:0;
            left:0;
            border-top:22px solid #08a1ef;
            border-right: 22px solid transparent;
        }
        .pagenum{
            font-size: 12px;
            color: #fff;
            position: absolute;
            top: -23px;
            left: 2px;
        }
            #navBar::-webkit-scrollbar{
            width: 8px;
            background-color: #f5f5f5;
        }
            #navBar::-webkit-scrollbar-track{
            -webkit-box-shadow: inset 0 0 4px rgba(0,0,0,.3);
            border-radius: 8px;
            background-color: #fff;
        }
            #navBar::-webkit-scrollbar-thumb{
            border-radius: 8px;
            -webkit-box-shadow: inset 0 0 4px rgba(0,0,0,.3);
            background-color: #6b6b70;
        }
        #navBar::-webkit-scrollbar-thumb:hover{
            background-color: #4a4a4f;
        }
</style>
  </head>
  <body>
    <div id="main-area">
      <div id="content-info">
        <div id="content-info">
          <div id="title">设计模式之美2-结构型</div>
        </div>
        <div id="author-info">
          <div id="author-name" class="text">sangjiacun</div>
          <div id="share-time" class="text">2020-05-14</div>
        </div>
      </div>
      <div id="main-content">
        <div id="svg-container"><svg ed:name="Page-1" xmlns="http://www.w3.org/2000/svg" width="3131" xmlns:xlink="http://www.w3.org/1999/xlink" height="5045" ed:hSpacing="30" xmlns:ev="http://www.w3.org/2001/xml-events" ed:vSpacing="30" id="page1" preserveAspectRadio="xMinYMin meet" xmlns:ed="https://www.edrawsoft.cn/xml/2017/SVGExtensions/" viewBox="0 0 3131 5045">
    <style type="text/css"><![CDATA[
g[ed\:togtopicid],g[ed\:hyperlink],g[ed\:comment],g[ed\:note] {cursor:pointer;}
g[id] {-moz-user-select: none;-ms-user-select: none;user-select: none;}
svg text::selection,svg tspan::selection{background-color: #4285f4;color: #ffffff;fill: #ffffff;}
.st29 {fill:#000000;font-family:宋体;font-size:11.25pt}
.st34 {fill:#00b0f0;font-family:宋体;font-size:9pt}
.st33 {fill:#00b0f0}
.st28 {fill:#303030;font-family:宋体;font-size:11.25pt}
.st30 {fill:#454545;font-family:宋体;font-size:9pt}
.st32 {fill:#454545}
.st36 {fill:#7030a0;font-family:宋体;font-size:9pt}
.st31 {fill:#ff0000;font-family:宋体;font-size:9pt}
.st35 {fill:#ff0000}
.st27 {fill:#ffffff;font-family:宋体;font-size:14.25pt}
]]></style>
    <defs>
        <linearGradient id="lg3" x2="0%" x1="0%" y1="0%" y2="100%">
            <stop offset="0" stop-color="#ffffff"/>
            <stop offset="0.25" stop-color="#f0f5f0"/>
            <stop offset="0.75" stop-color="#e1ebe1"/>
            <stop offset="1" stop-color="#c8d7c8"/>
        </linearGradient>
    </defs>
    <rect width="3131" height="5045" fill="#ffffff" y="0" x="0"/>
    <path ed:tosuperid="103" stroke-linecap="round" fill="none" d="M59.5,812.4L87.5,812.4L87.5,-812.4L122.5,-812.4" id="117" transform="matrix(1,0,0,1,1499,1710)" stroke="#696969" stroke-linejoin="round" ed:parentid="101"/>
    <path ed:tosuperid="104" stroke-linecap="round" fill="none" d="M59.5,153.5L87.5,153.5L87.5,-153.5L122.5,-153.5" id="118" transform="matrix(1,0,0,1,1499,2369)" stroke="#696969" stroke-linejoin="round" ed:parentid="101"/>
    <path ed:tosuperid="106" stroke-linecap="round" fill="none" d="M59.5,-923.1L87.5,-923.1L87.5,923.1L122.5,923.1" id="119" transform="matrix(1,0,0,1,1499,3446)" stroke="#696969" stroke-linejoin="round" ed:parentid="101"/>
    <path ed:tosuperid="107" stroke-linecap="round" fill="none" d="M-59.5,-419L-87.5,-419L-87.5,419L-122.5,419" id="120" transform="matrix(1,0,0,1,1254,2942)" stroke="#696969" stroke-linejoin="round" ed:parentid="101"/>
    <path ed:tosuperid="105" stroke-linecap="round" fill="none" d="M59.5,-323L87.5,-323L87.5,323L122.5,323" id="121" transform="matrix(1,0,0,1,1499,2846)" stroke="#696969" stroke-linejoin="round" ed:parentid="101"/>
    <path ed:tosuperid="108" stroke-linecap="round" fill="none" d="M-59.5,-146L-87.5,-146L-87.5,146L-122.5,146" id="122" transform="matrix(1,0,0,1,1254,2669)" stroke="#696969" stroke-linejoin="round" ed:parentid="101"/>
    <path ed:tosuperid="109" stroke-linecap="round" fill="none" d="M-59.5,273L-87.5,273L-87.5,-273L-122.5,-273" id="123" transform="matrix(1,0,0,1,1254,2250)" stroke="#696969" stroke-linejoin="round" ed:parentid="101"/>
    <path ed:tosuperid="126" stroke-linecap="round" fill="none" d="M-13.5,428.1L3.7,428.1L3.7,-428.1L13.5,-428.1" id="127" transform="matrix(1,0,0,1,1759,470)" stroke="#696969" stroke-linejoin="round" ed:parentid="103"/>
    <path ed:tosuperid="128" stroke-linecap="round" fill="none" d="M3.7,271.9L3.7,-271.9L13.5,-271.9" id="129" transform="matrix(1,0,0,1,1759,626)" stroke="#696969" stroke-linejoin="round" ed:parentid="103"/>
    <path ed:tosuperid="130" stroke-linecap="round" fill="none" d="M-13.5,90.3L3.7,90.3L3.7,-90.3L13.5,-90.3" id="131" transform="matrix(1,0,0,1,1976,264)" stroke="#696969" stroke-linejoin="round" ed:parentid="128"/>
    <path ed:tosuperid="132" stroke-linecap="round" fill="none" d="M3.7,-44.4L3.7,44.4L13.5,44.4" id="133" transform="matrix(1,0,0,1,1976,398)" stroke="#696969" stroke-linejoin="round" ed:parentid="128"/>
    <path ed:tosuperid="134" stroke-linecap="round" fill="none" d="M3.7,51.3L3.7,-51.3L13.5,-51.3" id="135" transform="matrix(1,0,0,1,1759,847)" stroke="#696969" stroke-linejoin="round" ed:parentid="103"/>
    <path ed:tosuperid="136" stroke-linecap="round" fill="none" d="M3.7,-205.5L3.7,205.5L13.5,205.5" id="137" transform="matrix(1,0,0,1,1759,1103)" stroke="#696969" stroke-linejoin="round" ed:parentid="103"/>
    <path ed:tosuperid="138" stroke-linecap="round" fill="none" d="M-13.5,46.8L3.7,46.8L3.7,-46.8L13.5,-46.8" id="139" transform="matrix(1,0,0,1,2141,127)" stroke="#696969" stroke-linejoin="round" ed:parentid="130"/>
    <path ed:tosuperid="140" stroke-linecap="round" fill="none" d="M3.7,-12.5L3.7,12.5L13.5,12.5" id="141" transform="matrix(1,0,0,1,2141,186)" stroke="#696969" stroke-linejoin="round" ed:parentid="130"/>
    <path ed:tosuperid="142" stroke-linecap="round" fill="none" d="M-13.5,9.4L3.7,9.4L3.7,-9.4L13.5,-9.4" id="143" transform="matrix(1,0,0,1,2273,433)" stroke="#696969" stroke-linejoin="round" ed:parentid="132"/>
    <path ed:tosuperid="144" stroke-linecap="round" fill="none" d="M3.7,-121.9L3.7,121.9L13.5,121.9" id="145" transform="matrix(1,0,0,1,1976,476)" stroke="#696969" stroke-linejoin="round" ed:parentid="128"/>
    <path ed:tosuperid="146" stroke-linecap="round" fill="none" d="M-13.5,5.1L3.7,5.1L3.7,-5.1L13.5,-5.1" id="147" transform="matrix(1,0,0,1,2141,593)" stroke="#696969" stroke-linejoin="round" ed:parentid="144"/>
    <path ed:tosuperid="148" stroke-linecap="round" fill="none" d="M-13.5,13.6L3.7,13.6L3.7,-13.6L13.5,-13.6" id="149" transform="matrix(1,0,0,1,2020,782)" stroke="#696969" stroke-linejoin="round" ed:parentid="134"/>
    <path ed:tosuperid="150" stroke-linecap="round" fill="none" d="M-13.5,178.9L3.7,178.9L3.7,-178.9L13.5,-178.9" id="151" transform="matrix(1,0,0,1,1948,1130)" stroke="#696969" stroke-linejoin="round" ed:parentid="136"/>
    <path ed:tosuperid="152" stroke-linecap="round" fill="none" d="M3.7,165.4L3.7,-165.4L13.5,-165.4" id="153" transform="matrix(1,0,0,1,1948,1143)" stroke="#696969" stroke-linejoin="round" ed:parentid="136"/>
    <path ed:tosuperid="154" stroke-linecap="round" fill="none" d="M3.7,-19.4L3.7,19.4L13.5,19.4" id="155" transform="matrix(1,0,0,1,1948,1328)" stroke="#696969" stroke-linejoin="round" ed:parentid="136"/>
    <path ed:tosuperid="156" stroke-linecap="round" fill="none" d="M3.7,143.4L3.7,-143.4L13.5,-143.4" id="157" transform="matrix(1,0,0,1,1948,1165)" stroke="#696969" stroke-linejoin="round" ed:parentid="136"/>
    <path ed:tosuperid="158" stroke-linecap="round" fill="none" d="M-13.5,-8.5L3.7,-8.5L3.7,8.5L13.5,8.5" id="159" transform="matrix(1,0,0,1,2254,1031)" stroke="#696969" stroke-linejoin="round" ed:parentid="156"/>
    <path ed:tosuperid="160" stroke-linecap="round" fill="none" d="M3.7,-413.9L3.7,413.9L13.5,413.9" id="161" transform="matrix(1,0,0,1,1759,1312)" stroke="#696969" stroke-linejoin="round" ed:parentid="103"/>
    <path ed:tosuperid="162" stroke-linecap="round" fill="none" d="M-13.5,17.8L3.7,17.8L3.7,-17.8L13.5,-17.8" id="163" transform="matrix(1,0,0,1,1912,1708)" stroke="#696969" stroke-linejoin="round" ed:parentid="160"/>
    <path ed:tosuperid="164" stroke-linecap="round" fill="none" d="M3.7,-2L3.7,2L13.5,2" id="165" transform="matrix(1,0,0,1,1912,1728)" stroke="#696969" stroke-linejoin="round" ed:parentid="160"/>
    <path ed:tosuperid="166" stroke-linecap="round" fill="none" d="M-13.5,6.8L3.7,6.8L3.7,-6.8L13.5,-6.8" id="167" transform="matrix(1,0,0,1,2128,1683)" stroke="#696969" stroke-linejoin="round" ed:parentid="162"/>
    <path ed:tosuperid="168" stroke-linecap="round" fill="none" d="M3.7,-6.8L3.7,6.8L13.5,6.8" id="169" transform="matrix(1,0,0,1,2128,1697)" stroke="#696969" stroke-linejoin="round" ed:parentid="162"/>
    <path ed:tosuperid="170" stroke-linecap="round" fill="none" d="M3.7,-20.3L3.7,20.3L13.5,20.3" id="171" transform="matrix(1,0,0,1,1912,1746)" stroke="#696969" stroke-linejoin="round" ed:parentid="160"/>
    <path ed:tosuperid="172" stroke-linecap="round" fill="none" d="M-13.5,-4.3L3.7,-4.3L3.7,4.3L13.5,4.3" id="173" transform="matrix(1,0,0,1,2020,1770)" stroke="#696969" stroke-linejoin="round" ed:parentid="170"/>
    <path ed:tosuperid="174" stroke-linecap="round" fill="none" d="M-13.5,-0.5L3.7,-0.5L3.7,0.5L13.5,0.5" id="175" transform="matrix(1,0,0,1,1994,1730)" stroke="#696969" stroke-linejoin="round" ed:parentid="164"/>
    <path ed:tosuperid="176" stroke-linecap="round" fill="none" d="M0,-19.5L0,19.5" id="177" transform="matrix(1,0,0,1,1324,2122)" stroke="#696969" stroke-linejoin="round" ed:parentid="125"/>
    <path ed:tosuperid="178" stroke-linecap="round" fill="none" d="M-13.5,193.8L3.7,193.8L3.7,-193.8L13.5,-193.8" id="179" transform="matrix(1,0,0,1,1759,2022)" stroke="#696969" stroke-linejoin="round" ed:parentid="104"/>
    <path ed:tosuperid="181" stroke-linecap="round" fill="none" d="M3.7,162.5L3.7,-162.5L13.5,-162.5" id="182" transform="matrix(1,0,0,1,1759,2053)" stroke="#696969" stroke-linejoin="round" ed:parentid="104"/>
    <path ed:tosuperid="183" stroke-linecap="round" fill="none" d="M-13.5,17.8L3.7,17.8L3.7,-17.8L13.5,-17.8" id="184" transform="matrix(1,0,0,1,1859,1873)" stroke="#696969" stroke-linejoin="round" ed:parentid="181"/>
    <path ed:tosuperid="185" stroke-linecap="round" fill="none" d="M-13.5,0L3.7,0L13.5,0" id="186" transform="matrix(1,0,0,1,2042,1855)" stroke="#696969" stroke-linejoin="round" ed:parentid="183"/>
    <path ed:tosuperid="187" stroke-linecap="round" fill="none" d="M3.7,4.3L3.7,-4.3L13.5,-4.3" id="188" transform="matrix(1,0,0,1,1860,1886)" stroke="#696969" stroke-linejoin="round" ed:parentid="181"/>
    <path ed:tosuperid="189" stroke-linecap="round" fill="none" d="M-13.5,0L3.7,0L13.5,0" id="190" transform="matrix(1,0,0,1,2212,1882)" stroke="#696969" stroke-linejoin="round" ed:parentid="187"/>
    <path ed:tosuperid="191" stroke-linecap="round" fill="none" d="M3.7,-17.8L3.7,17.8L13.5,17.8" id="192" transform="matrix(1,0,0,1,1859,1908)" stroke="#696969" stroke-linejoin="round" ed:parentid="181"/>
    <path ed:tosuperid="193" stroke-linecap="round" fill="none" d="M-13.5,128.1L3.7,128.1L3.7,-128.1L13.5,-128.1" id="194" transform="matrix(1,0,0,1,1852,2160)" stroke="#696969" stroke-linejoin="round" ed:parentid="195"/>
    <path ed:tosuperid="195" stroke-linecap="round" fill="none" d="M3.7,-36.4L3.7,36.4L13.5,36.4" id="196" transform="matrix(1,0,0,1,1759,2252)" stroke="#696969" stroke-linejoin="round" ed:parentid="104"/>
    <path ed:tosuperid="197" stroke-linecap="round" fill="none" d="M3.7,-23.9L3.7,23.9L13.5,23.9" id="198" transform="matrix(1,0,0,1,1852,2312)" stroke="#696969" stroke-linejoin="round" ed:parentid="195"/>
    <path ed:tosuperid="199" stroke-linecap="round" fill="none" d="M3.7,-146.9L3.7,146.9L13.5,146.9" id="200" transform="matrix(1,0,0,1,1852,2435)" stroke="#696969" stroke-linejoin="round" ed:parentid="195"/>
    <path ed:tosuperid="201" stroke-linecap="round" fill="none" d="M-13.5,245.8L3.7,245.8L3.7,-245.8L13.5,-245.8" id="202" transform="matrix(1,0,0,1,1774,2923)" stroke="#696969" stroke-linejoin="round" ed:parentid="105"/>
    <path ed:tosuperid="203" stroke-linecap="round" fill="none" d="M3.7,127L3.7,-127L13.5,-127" id="204" transform="matrix(1,0,0,1,1774,3042)" stroke="#696969" stroke-linejoin="round" ed:parentid="105"/>
    <path ed:tosuperid="205" stroke-linecap="round" fill="none" d="M-13.5,43.3L3.7,43.3L3.7,-43.3L13.5,-43.3" id="206" transform="matrix(1,0,0,1,1865,2871)" stroke="#696969" stroke-linejoin="round" ed:parentid="203"/>
    <path ed:tosuperid="207" stroke-linecap="round" fill="none" d="M3.7,-69.3L3.7,69.3L13.5,69.3" id="208" transform="matrix(1,0,0,1,1865,2984)" stroke="#696969" stroke-linejoin="round" ed:parentid="203"/>
    <path ed:tosuperid="209" stroke-linecap="round" fill="none" d="M-13.5,38L3.7,38L3.7,-38L13.5,-38" id="210" transform="matrix(1,0,0,1,1946,2790)" stroke="#696969" stroke-linejoin="round" ed:parentid="205"/>
    <path ed:tosuperid="211" stroke-linecap="round" fill="none" d="M3.7,-30.8L3.7,30.8L13.5,30.8" id="212" transform="matrix(1,0,0,1,1946,2859)" stroke="#696969" stroke-linejoin="round" ed:parentid="205"/>
    <path ed:tosuperid="213" stroke-linecap="round" fill="none" d="M-13.5,25.5L3.7,25.5L3.7,-25.5L13.5,-25.5" id="214" transform="matrix(1,0,0,1,1946,3028)" stroke="#696969" stroke-linejoin="round" ed:parentid="207"/>
    <path ed:tosuperid="215" stroke-linecap="round" fill="none" d="M3.7,-18.3L3.7,18.3L13.5,18.3" id="216" transform="matrix(1,0,0,1,1946,3071)" stroke="#696969" stroke-linejoin="round" ed:parentid="207"/>
    <path ed:tosuperid="217" stroke-linecap="round" fill="none" d="M-13.5,25L3.7,25L3.7,-25L13.5,-25" id="218" transform="matrix(1,0,0,1,2062,2727)" stroke="#696969" stroke-linejoin="round" ed:parentid="209"/>
    <path ed:tosuperid="219" stroke-linecap="round" fill="none" d="M3.7,6.3L3.7,-6.3L13.5,-6.3" id="220" transform="matrix(1,0,0,1,2062,2746)" stroke="#696969" stroke-linejoin="round" ed:parentid="209"/>
    <path ed:tosuperid="221" stroke-linecap="round" fill="none" d="M3.7,-12.5L3.7,12.5L13.5,12.5" id="222" transform="matrix(1,0,0,1,2062,2765)" stroke="#696969" stroke-linejoin="round" ed:parentid="209"/>
    <path ed:tosuperid="223" stroke-linecap="round" fill="none" d="M3.7,-25L3.7,25L13.5,25" id="224" transform="matrix(1,0,0,1,2062,2777)" stroke="#696969" stroke-linejoin="round" ed:parentid="209"/>
    <path ed:tosuperid="225" stroke-linecap="round" fill="none" d="M-13.5,6.3L3.7,6.3L3.7,-6.3L13.5,-6.3" id="226" transform="matrix(1,0,0,1,2207,2733)" stroke="#696969" stroke-linejoin="round" ed:parentid="219"/>
    <path ed:tosuperid="227" stroke-linecap="round" fill="none" d="M3.7,-6.3L3.7,6.3L13.5,6.3" id="228" transform="matrix(1,0,0,1,2207,2746)" stroke="#696969" stroke-linejoin="round" ed:parentid="219"/>
    <path ed:tosuperid="229" stroke-linecap="round" fill="none" d="M-13.5,31.3L3.7,31.3L3.7,-31.3L13.5,-31.3" id="230" transform="matrix(1,0,0,1,2072,2858)" stroke="#696969" stroke-linejoin="round" ed:parentid="211"/>
    <path ed:tosuperid="231" stroke-linecap="round" fill="none" d="M3.7,6.3L3.7,-6.3L13.5,-6.3" id="232" transform="matrix(1,0,0,1,2072,2883)" stroke="#696969" stroke-linejoin="round" ed:parentid="211"/>
    <path ed:tosuperid="233" stroke-linecap="round" fill="none" d="M3.7,-18.8L3.7,18.8L13.5,18.8" id="234" transform="matrix(1,0,0,1,2072,2908)" stroke="#696969" stroke-linejoin="round" ed:parentid="211"/>
    <path ed:tosuperid="235" stroke-linecap="round" fill="none" d="M3.7,-31.3L3.7,31.3L13.5,31.3" id="236" transform="matrix(1,0,0,1,2072,2921)" stroke="#696969" stroke-linejoin="round" ed:parentid="211"/>
    <path ed:tosuperid="237" stroke-linecap="round" fill="none" d="M-13.5,12.5L3.7,12.5L3.7,-12.5L13.5,-12.5" id="238" transform="matrix(1,0,0,1,2227,2865)" stroke="#696969" stroke-linejoin="round" ed:parentid="231"/>
    <path ed:tosuperid="239" stroke-linecap="round" fill="none" d="M3.7,0L13.5,0" id="240" transform="matrix(1,0,0,1,2227,2877)" stroke="#696969" stroke-linejoin="round" ed:parentid="231"/>
    <path ed:tosuperid="241" stroke-linecap="round" fill="none" d="M3.7,-12.5L3.7,12.5L13.5,12.5" id="242" transform="matrix(1,0,0,1,2227,2890)" stroke="#696969" stroke-linejoin="round" ed:parentid="231"/>
    <path ed:tosuperid="243" stroke-linecap="round" fill="none" d="M-13.5,12.5L3.7,12.5L3.7,-12.5L13.5,-12.5" id="244" transform="matrix(1,0,0,1,2031,2990)" stroke="#696969" stroke-linejoin="round" ed:parentid="213"/>
    <path ed:tosuperid="245" stroke-linecap="round" fill="none" d="M3.7,0L13.5,0" id="246" transform="matrix(1,0,0,1,2031,3002)" stroke="#696969" stroke-linejoin="round" ed:parentid="213"/>
    <path ed:tosuperid="247" stroke-linecap="round" fill="none" d="M3.7,-12.5L3.7,12.5L13.5,12.5" id="248" transform="matrix(1,0,0,1,2031,3015)" stroke="#696969" stroke-linejoin="round" ed:parentid="213"/>
    <path ed:tosuperid="249" stroke-linecap="round" fill="none" d="M-13.5,0L3.7,0L13.5,0" id="250" transform="matrix(1,0,0,1,2175,3002)" stroke="#696969" stroke-linejoin="round" ed:parentid="245"/>
    <path ed:tosuperid="252" stroke-linecap="round" fill="none" d="M-13.5,18.8L3.7,18.8L3.7,-18.8L13.5,-18.8" id="253" transform="matrix(1,0,0,1,2026,3071)" stroke="#696969" stroke-linejoin="round" ed:parentid="215"/>
    <path ed:tosuperid="254" stroke-linecap="round" fill="none" d="M3.7,6.3L3.7,-6.3L13.5,-6.3" id="255" transform="matrix(1,0,0,1,2026,3083)" stroke="#696969" stroke-linejoin="round" ed:parentid="215"/>
    <path ed:tosuperid="256" stroke-linecap="round" fill="none" d="M3.7,-6.3L3.7,6.3L13.5,6.3" id="257" transform="matrix(1,0,0,1,2026,3096)" stroke="#696969" stroke-linejoin="round" ed:parentid="215"/>
    <path ed:tosuperid="258" stroke-linecap="round" fill="none" d="M3.7,-18.8L3.7,18.8L13.5,18.8" id="259" transform="matrix(1,0,0,1,2026,3108)" stroke="#696969" stroke-linejoin="round" ed:parentid="215"/>
    <path ed:tosuperid="260" stroke-linecap="round" fill="none" d="M-13.5,0L3.7,0L13.5,0" id="261" transform="matrix(1,0,0,1,2186,3077)" stroke="#696969" stroke-linejoin="round" ed:parentid="254"/>
    <path ed:tosuperid="262" stroke-linecap="round" fill="none" d="M3.7,-124.4L3.7,124.4L13.5,124.4" id="263" transform="matrix(1,0,0,1,1774,3293)" stroke="#696969" stroke-linejoin="round" ed:parentid="105"/>
    <path ed:tosuperid="264" stroke-linecap="round" fill="none" d="M-13.5,120.8L3.7,120.8L3.7,-120.8L13.5,-120.8" id="265" transform="matrix(1,0,0,1,1977,3297)" stroke="#696969" stroke-linejoin="round" ed:parentid="262"/>
    <path ed:tosuperid="266" stroke-linecap="round" fill="none" d="M-13.5,5.1L3.7,5.1L3.7,-5.1L13.5,-5.1" id="267" transform="matrix(1,0,0,1,2447,3171)" stroke="#696969" stroke-linejoin="round" ed:parentid="264"/>
    <path ed:tosuperid="268" stroke-linecap="round" fill="none" d="M3.7,-17.6L3.7,17.6L13.5,17.6" id="269" transform="matrix(1,0,0,1,1977,3435)" stroke="#696969" stroke-linejoin="round" ed:parentid="262"/>
    <path ed:tosuperid="270" stroke-linecap="round" fill="none" d="M-13.5,56.6L3.7,56.6L3.7,-56.6L13.5,-56.6" id="271" transform="matrix(1,0,0,1,2390,3396)" stroke="#696969" stroke-linejoin="round" ed:parentid="268"/>
    <path ed:tosuperid="272" stroke-linecap="round" fill="none" d="M3.7,-64.1L3.7,64.1L13.5,64.1" id="273" transform="matrix(1,0,0,1,2390,3517)" stroke="#696969" stroke-linejoin="round" ed:parentid="268"/>
    <path ed:tosuperid="274" stroke-linecap="round" fill="none" d="M-13.5,5.1L3.7,5.1L3.7,-5.1L13.5,-5.1" id="275" transform="matrix(1,0,0,1,2771,3334)" stroke="#696969" stroke-linejoin="round" ed:parentid="270"/>
    <path ed:tosuperid="276" stroke-linecap="round" fill="none" d="M-13.5,5.1L3.7,5.1L3.7,-5.1L13.5,-5.1" id="277" transform="matrix(1,0,0,1,2759,3576)" stroke="#696969" stroke-linejoin="round" ed:parentid="272"/>
    <path ed:tosuperid="278" stroke-linecap="round" fill="none" d="M-13.5,317.4L3.7,317.4L3.7,-317.4L13.5,-317.4" id="279" transform="matrix(1,0,0,1,1774,4051)" stroke="#696969" stroke-linejoin="round" ed:parentid="106"/>
    <path ed:tosuperid="280" stroke-linecap="round" fill="none" d="M3.7,220.3L3.7,-220.3L13.5,-220.3" id="281" transform="matrix(1,0,0,1,1774,4149)" stroke="#696969" stroke-linejoin="round" ed:parentid="106"/>
    <path ed:tosuperid="282" stroke-linecap="round" fill="none" d="M3.7,62L3.7,-62L13.5,-62" id="283" transform="matrix(1,0,0,1,1774,4307)" stroke="#696969" stroke-linejoin="round" ed:parentid="106"/>
    <path ed:tosuperid="284" stroke-linecap="round" fill="none" d="M-13.5,0L3.7,0L13.5,0" id="285" transform="matrix(1,0,0,1,1867,3928)" stroke="#696969" stroke-linejoin="round" ed:parentid="280"/>
    <path ed:tosuperid="286" stroke-linecap="round" fill="none" d="M-13.5,0L3.7,0L13.5,0" id="287" transform="matrix(1,0,0,1,1879,4245)" stroke="#696969" stroke-linejoin="round" ed:parentid="282"/>
    <path ed:tosuperid="288" stroke-linecap="round" fill="none" d="M-13.5,5.1L3.7,5.1L3.7,-5.1L13.5,-5.1" id="289" transform="matrix(1,0,0,1,2020,3923)" stroke="#696969" stroke-linejoin="round" ed:parentid="284"/>
    <path ed:tosuperid="290" stroke-linecap="round" fill="none" d="M-13.5,5.1L3.7,5.1L3.7,-5.1L13.5,-5.1" id="291" transform="matrix(1,0,0,1,2032,4240)" stroke="#696969" stroke-linejoin="round" ed:parentid="286"/>
    <path ed:tosuperid="292" stroke-linecap="round" fill="none" d="M3.7,-37.1L3.7,37.1L13.5,37.1" id="293" transform="matrix(1,0,0,1,1774,4406)" stroke="#696969" stroke-linejoin="round" ed:parentid="106"/>
    <path ed:tosuperid="294" stroke-linecap="round" fill="none" d="M-13.5,24.5L3.7,24.5L3.7,-24.5L13.5,-24.5" id="295" transform="matrix(1,0,0,1,2025,4419)" stroke="#696969" stroke-linejoin="round" ed:parentid="292"/>
    <path ed:tosuperid="296" stroke-linecap="round" fill="none" d="M3.7,11L3.7,-11L13.5,-11" id="297" transform="matrix(1,0,0,1,2025,4432)" stroke="#696969" stroke-linejoin="round" ed:parentid="292"/>
    <path ed:tosuperid="298" stroke-linecap="round" fill="none" d="M3.7,-13.5L3.7,13.5L13.5,13.5" id="299" transform="matrix(1,0,0,1,2025,4457)" stroke="#696969" stroke-linejoin="round" ed:parentid="292"/>
    <path ed:tosuperid="302" stroke-linecap="round" fill="none" d="M-13.5,6.8C-1.1,6.8,1.7,-6.8,13.5,-6.8" id="303" transform="matrix(1,0,0,1,2197,4463)" stroke="#696969" stroke-linejoin="round" ed:parentid="298"/>
    <path ed:tosuperid="304" stroke-linecap="round" fill="none" d="M-13.5,-11C-0.2,-11,-0.5,11,13.5,11" id="305" transform="matrix(1,0,0,1,2197,4481)" stroke="#696969" stroke-linejoin="round" ed:parentid="298"/>
    <path ed:tosuperid="306" stroke-linecap="round" fill="none" d="M-13.5,-4.3C-1.7,-4.3,3.1,4.3,13.5,4.3" id="307" transform="matrix(1,0,0,1,2582,4461)" stroke="#696969" stroke-linejoin="round" ed:parentid="302"/>
    <path ed:tosuperid="308" stroke-linecap="round" fill="none" d="M-13.5,0C-2.7,0,5.4,0,13.5,0" id="309" transform="matrix(1,0,0,1,2606,4492)" stroke="#696969" stroke-linejoin="round" ed:parentid="304"/>
    <path ed:tosuperid="310" stroke-linecap="round" fill="none" d="M3.7,-149.9L3.7,149.9L13.5,149.9" id="311" transform="matrix(1,0,0,1,1774,4519)" stroke="#696969" stroke-linejoin="round" ed:parentid="106"/>
    <path ed:tosuperid="312" stroke-linecap="round" fill="none" d="M-13.5,74.8C5.4,74.8,-13.5,-74.8,13.5,-74.8" id="313" transform="matrix(1,0,0,1,1951,4594)" stroke="#696969" stroke-linejoin="round" ed:parentid="310"/>
    <path ed:tosuperid="314" stroke-linecap="round" fill="none" d="M-13.5,57C5.4,57,-13.5,-57,13.5,-57" id="315" transform="matrix(1,0,0,1,1951,4612)" stroke="#696969" stroke-linejoin="round" ed:parentid="310"/>
    <path ed:tosuperid="316" stroke-linecap="round" fill="none" d="M-13.5,-4.3C-1.7,-4.3,3.1,4.3,13.5,4.3" id="317" transform="matrix(1,0,0,1,2131,4559)" stroke="#696969" stroke-linejoin="round" ed:parentid="314"/>
    <path ed:tosuperid="318" stroke-linecap="round" fill="none" d="M-13.5,19.8C1.7,19.8,-4.9,-19.8,13.5,-19.8" id="319" transform="matrix(1,0,0,1,1951,4649)" stroke="#696969" stroke-linejoin="round" ed:parentid="310"/>
    <path ed:tosuperid="320" stroke-linecap="round" fill="none" d="M-13.5,11C-0.2,11,-0.5,-11,13.5,-11" id="321" transform="matrix(1,0,0,1,2131,4618)" stroke="#696969" stroke-linejoin="round" ed:parentid="318"/>
    <path ed:tosuperid="324" stroke-linecap="round" fill="none" d="M-13.5,-19.5C1.7,-19.5,-4.8,19.5,13.5,19.5" id="325" transform="matrix(1,0,0,1,2131,4649)" stroke="#696969" stroke-linejoin="round" ed:parentid="318"/>
    <path ed:tosuperid="326" stroke-linecap="round" fill="none" d="M-13.5,-13.3C0.3,-13.3,-1.7,13.3,13.5,13.3" id="327" transform="matrix(1,0,0,1,1951,4682)" stroke="#696969" stroke-linejoin="round" ed:parentid="310"/>
    <path ed:tosuperid="328" stroke-linecap="round" fill="none" d="M-13.5,0C-2.7,0,5.4,0,13.5,0" id="329" transform="matrix(1,0,0,1,2119,4695)" stroke="#696969" stroke-linejoin="round" ed:parentid="326"/>
    <path ed:tosuperid="330" stroke-linecap="round" fill="none" d="M-13.5,-26.8C3,-26.8,-7.9,26.8,13.5,26.8" id="331" transform="matrix(1,0,0,1,1951,4695)" stroke="#696969" stroke-linejoin="round" ed:parentid="310"/>
    <path ed:tosuperid="332" stroke-linecap="round" fill="none" d="M-13.5,0C-2.7,0,5.4,0,13.5,0" id="333" transform="matrix(1,0,0,1,2095,4722)" stroke="#696969" stroke-linejoin="round" ed:parentid="330"/>
    <path ed:tosuperid="334" stroke-linecap="round" fill="none" d="M-13.5,-53.3C5.4,-53.3,-13.5,53.3,13.5,53.3" id="335" transform="matrix(1,0,0,1,1951,4722)" stroke="#696969" stroke-linejoin="round" ed:parentid="310"/>
    <path ed:tosuperid="336" stroke-linecap="round" fill="none" d="M3.7,-244.9L3.7,244.9L13.5,244.9" id="337" transform="matrix(1,0,0,1,1774,4614)" stroke="#696969" stroke-linejoin="round" ed:parentid="106"/>
    <path ed:tosuperid="338" stroke-linecap="round" fill="none" d="M-13.5,13C0.3,13,-1.6,-13,13.5,-13" id="339" transform="matrix(1,0,0,1,2119,4762)" stroke="#696969" stroke-linejoin="round" ed:parentid="334"/>
    <path ed:tosuperid="340" stroke-linecap="round" fill="none" d="M-13.5,-0.5C-2.7,-0.5,5.4,0.5,13.5,0.5" id="341" transform="matrix(1,0,0,1,2119,4776)" stroke="#696969" stroke-linejoin="round" ed:parentid="334"/>
    <path ed:tosuperid="342" stroke-linecap="round" fill="none" d="M-13.5,-13C0.3,-13,-1.6,13,13.5,13" id="343" transform="matrix(1,0,0,1,2119,4788)" stroke="#696969" stroke-linejoin="round" ed:parentid="334"/>
    <path ed:tosuperid="344" stroke-linecap="round" fill="none" d="M-13.5,6.8C-1.1,6.8,1.7,-6.8,13.5,-6.8" id="345" transform="matrix(1,0,0,1,2018,4852)" stroke="#696969" stroke-linejoin="round" ed:parentid="336"/>
    <path ed:tosuperid="346" stroke-linecap="round" fill="none" d="M-13.5,-15.3C0.8,-15.3,-2.7,15.3,13.5,15.3" id="347" transform="matrix(1,0,0,1,2018,4874)" stroke="#696969" stroke-linejoin="round" ed:parentid="336"/>
    <path ed:tosuperid="348" stroke-linecap="round" fill="none" d="M3.7,-300.6L3.7,300.6L13.5,300.6" id="349" transform="matrix(1,0,0,1,1774,4669)" stroke="#696969" stroke-linejoin="round" ed:parentid="106"/>
    <path ed:tosuperid="350" stroke-linecap="round" fill="none" d="M-13.5,27C3,27,-8,-27,13.5,-27" id="351" transform="matrix(1,0,0,1,2086,4943)" stroke="#696969" stroke-linejoin="round" ed:parentid="348"/>
    <path ed:tosuperid="352" stroke-linecap="round" fill="none" d="M-13.5,13.5C0.4,13.5,-1.8,-13.5,13.5,-13.5" id="353" transform="matrix(1,0,0,1,2086,4957)" stroke="#696969" stroke-linejoin="round" ed:parentid="348"/>
    <path ed:tosuperid="354" stroke-linecap="round" fill="none" d="M-13.5,0C-2.7,0,5.4,0,13.5,0" id="355" transform="matrix(1,0,0,1,2086,4970)" stroke="#696969" stroke-linejoin="round" ed:parentid="348"/>
    <path ed:tosuperid="356" stroke-linecap="round" fill="none" d="M-13.5,-13.5C0.4,-13.5,-1.8,13.5,13.5,13.5" id="357" transform="matrix(1,0,0,1,2086,4984)" stroke="#696969" stroke-linejoin="round" ed:parentid="348"/>
    <path ed:tosuperid="358" stroke-linecap="round" fill="none" d="M-13.5,-27C3,-27,-8,27,13.5,27" id="359" transform="matrix(1,0,0,1,2086,4997)" stroke="#696969" stroke-linejoin="round" ed:parentid="348"/>
    <path ed:tosuperid="360" stroke-linecap="round" fill="none" d="M13.5,13.5C-0.4,13.5,1.8,-13.5,-13.5,-13.5" id="361" transform="matrix(1,0,0,1,824,3241)" stroke="#696969" stroke-linejoin="round" ed:parentid="362"/>
    <path ed:tosuperid="362" stroke-linecap="round" fill="none" d="M13.5,53.1L-3.7,53.1L-3.7,-53.1L-13.5,-53.1" id="363" transform="matrix(1,0,0,1,989,3307)" stroke="#696969" stroke-linejoin="round" ed:parentid="107"/>
    <path ed:tosuperid="364" stroke-linecap="round" fill="none" d="M-3.7,-5.1L-3.7,5.1L-13.5,5.1" id="365" transform="matrix(1,0,0,1,989,3366)" stroke="#696969" stroke-linejoin="round" ed:parentid="107"/>
    <path ed:tosuperid="366" stroke-linecap="round" fill="none" d="M13.5,0C2.7,0,-5.4,0,-13.5,0" id="367" transform="matrix(1,0,0,1,824,3254)" stroke="#696969" stroke-linejoin="round" ed:parentid="362"/>
    <path ed:tosuperid="368" stroke-linecap="round" fill="none" d="M13.5,-13.5C-0.4,-13.5,1.8,13.5,-13.5,13.5" id="369" transform="matrix(1,0,0,1,824,3268)" stroke="#696969" stroke-linejoin="round" ed:parentid="362"/>
    <path ed:tosuperid="370" stroke-linecap="round" fill="none" d="M13.5,31.3C-3.7,31.3,9.5,-31.3,-13.5,-31.3" id="371" transform="matrix(1,0,0,1,812,3340)" stroke="#696969" stroke-linejoin="round" ed:parentid="364"/>
    <path ed:tosuperid="372" stroke-linecap="round" fill="none" d="M13.5,0C2.7,0,-5.4,0,-13.5,0" id="373" transform="matrix(1,0,0,1,668,3308)" stroke="#696969" stroke-linejoin="round" ed:parentid="370"/>
    <path ed:tosuperid="374" stroke-linecap="round" fill="none" d="M13.5,17.8C-1.3,17.8,3.9,-17.8,-13.5,-17.8" id="375" transform="matrix(1,0,0,1,812,3353)" stroke="#696969" stroke-linejoin="round" ed:parentid="364"/>
    <path ed:tosuperid="376" stroke-linecap="round" fill="none" d="M13.5,0C2.7,0,-5.4,0,-13.5,0" id="377" transform="matrix(1,0,0,1,680,3335)" stroke="#696969" stroke-linejoin="round" ed:parentid="374"/>
    <path ed:tosuperid="378" stroke-linecap="round" fill="none" d="M13.5,-13.5C-0.4,-13.5,1.8,13.5,-13.5,13.5" id="379" transform="matrix(1,0,0,1,812,3384)" stroke="#696969" stroke-linejoin="round" ed:parentid="364"/>
    <path ed:tosuperid="380" stroke-linecap="round" fill="none" d="M13.5,17.8C-1.3,17.8,3.9,-17.8,-13.5,-17.8" id="381" transform="matrix(1,0,0,1,644,3380)" stroke="#696969" stroke-linejoin="round" ed:parentid="378"/>
    <path ed:tosuperid="382" stroke-linecap="round" fill="none" d="M13.5,4.3C1.7,4.3,-3.1,-4.3,-13.5,-4.3" id="383" transform="matrix(1,0,0,1,644,3394)" stroke="#696969" stroke-linejoin="round" ed:parentid="378"/>
    <path ed:tosuperid="384" stroke-linecap="round" fill="none" d="M13.5,-17.8C-1.3,-17.8,3.9,17.8,-13.5,17.8" id="385" transform="matrix(1,0,0,1,644,3416)" stroke="#696969" stroke-linejoin="round" ed:parentid="378"/>
    <path ed:tosuperid="386" stroke-linecap="round" fill="none" d="M-3.7,-63.9L-3.7,63.9L-13.5,63.9" id="387" transform="matrix(1,0,0,1,989,3424)" stroke="#696969" stroke-linejoin="round" ed:parentid="107"/>
    <path ed:tosuperid="389" stroke-linecap="round" fill="none" d="M13.5,14C-0.5,14,2.1,-14,-13.5,-14" id="390" transform="matrix(1,0,0,1,877,3474)" stroke="#696969" stroke-linejoin="round" ed:parentid="386"/>
    <path ed:tosuperid="391" stroke-linecap="round" fill="none" d="M13.5,0.5C2.7,0.5,-5.4,-0.5,-13.5,-0.5" id="392" transform="matrix(1,0,0,1,877,3488)" stroke="#696969" stroke-linejoin="round" ed:parentid="386"/>
    <path ed:tosuperid="393" stroke-linecap="round" fill="none" d="M13.5,-13C-0.3,-13,1.6,13,-13.5,13" id="394" transform="matrix(1,0,0,1,877,3501)" stroke="#696969" stroke-linejoin="round" ed:parentid="386"/>
    <path ed:tosuperid="395" stroke-linecap="round" fill="none" d="M13.5,20.3C-1.8,20.3,5.1,-20.3,-13.5,-20.3" id="396" transform="matrix(1,0,0,1,820,2496)" stroke="#696969" stroke-linejoin="round" ed:parentid="399"/>
    <path ed:tosuperid="397" stroke-linecap="round" fill="none" d="M13.5,6.8C1.1,6.8,-1.7,-6.8,-13.5,-6.8" id="398" transform="matrix(1,0,0,1,820,2510)" stroke="#696969" stroke-linejoin="round" ed:parentid="399"/>
    <path ed:tosuperid="399" stroke-linecap="round" fill="none" d="M13.5,149.1L-3.7,149.1L-3.7,-149.1L-13.5,-149.1" id="400" transform="matrix(1,0,0,1,985,2665)" stroke="#696969" stroke-linejoin="round" ed:parentid="108"/>
    <path ed:tosuperid="401" stroke-linecap="round" fill="none" d="M13.5,-6.8C1.1,-6.8,-1.7,6.8,-13.5,6.8" id="402" transform="matrix(1,0,0,1,820,2523)" stroke="#696969" stroke-linejoin="round" ed:parentid="399"/>
    <path ed:tosuperid="403" stroke-linecap="round" fill="none" d="M13.5,-20.3C-1.8,-20.3,5.1,20.3,-13.5,20.3" id="404" transform="matrix(1,0,0,1,820,2537)" stroke="#696969" stroke-linejoin="round" ed:parentid="399"/>
    <path ed:tosuperid="405" stroke-linecap="round" fill="none" d="M-3.7,-32.1L-3.7,32.1L-13.5,32.1" id="406" transform="matrix(1,0,0,1,985,2847)" stroke="#696969" stroke-linejoin="round" ed:parentid="108"/>
    <path ed:tosuperid="407" stroke-linecap="round" fill="none" d="M13.5,147.5C-5.4,147.5,13.5,-147.5,-13.5,-147.5" id="408" transform="matrix(1,0,0,1,808,2731)" stroke="#696969" stroke-linejoin="round" ed:parentid="405"/>
    <path ed:tosuperid="418" stroke-linecap="round" fill="none" d="M13.5,71.5C-5.4,71.5,13.5,-71.5,-13.5,-71.5" id="419" transform="matrix(1,0,0,1,808,2807)" stroke="#696969" stroke-linejoin="round" ed:parentid="405"/>
    <path ed:tosuperid="420" stroke-linecap="round" fill="none" d="M13.5,-76C-5.4,-76,13.5,76,-13.5,76" id="421" transform="matrix(1,0,0,1,808,2955)" stroke="#696969" stroke-linejoin="round" ed:parentid="405"/>
    <path ed:tosuperid="422" stroke-linecap="round" fill="none" d="M13.5,201.6L-3.7,201.6L-3.7,-201.6L-13.5,-201.6" id="423" transform="matrix(1,0,0,1,985,1775)" stroke="#696969" stroke-linejoin="round" ed:parentid="109"/>
    <path ed:tosuperid="426" stroke-linecap="round" fill="none" d="M13.5,2.5C2.1,2.5,-4,-2.5,-13.5,-2.5" id="427" transform="matrix(1,0,0,1,832,1571)" stroke="#696969" stroke-linejoin="round" ed:parentid="422"/>
    <path ed:tosuperid="428" stroke-linecap="round" fill="none" d="M13.5,-11C0.2,-11,0.5,11,-13.5,11" id="429" transform="matrix(1,0,0,1,832,1584)" stroke="#696969" stroke-linejoin="round" ed:parentid="422"/>
    <path ed:tosuperid="430" stroke-linecap="round" fill="none" d="M-3.7,156.9L-3.7,-156.9L-13.5,-156.9" id="431" transform="matrix(1,0,0,1,985,1820)" stroke="#696969" stroke-linejoin="round" ed:parentid="109"/>
    <path ed:tosuperid="432" stroke-linecap="round" fill="none" d="M-3.7,112.1L-3.7,-112.1L-13.5,-112.1" id="433" transform="matrix(1,0,0,1,985,1864)" stroke="#696969" stroke-linejoin="round" ed:parentid="109"/>
    <path ed:tosuperid="434" stroke-linecap="round" fill="none" d="M-3.7,68.1L-3.7,-68.1L-13.5,-68.1" id="435" transform="matrix(1,0,0,1,985,1908)" stroke="#696969" stroke-linejoin="round" ed:parentid="109"/>
    <path ed:tosuperid="436" stroke-linecap="round" fill="none" d="M13.5,20.3C-1.8,20.3,5.1,-20.3,-13.5,-20.3" id="437" transform="matrix(1,0,0,1,848,1643)" stroke="#696969" stroke-linejoin="round" ed:parentid="430"/>
    <path ed:tosuperid="438" stroke-linecap="round" fill="none" d="M13.5,6.8C1.1,6.8,-1.7,-6.8,-13.5,-6.8" id="439" transform="matrix(1,0,0,1,848,1656)" stroke="#696969" stroke-linejoin="round" ed:parentid="430"/>
    <path ed:tosuperid="440" stroke-linecap="round" fill="none" d="M13.5,-6.8C1.1,-6.8,-1.7,6.8,-13.5,6.8" id="441" transform="matrix(1,0,0,1,848,1670)" stroke="#696969" stroke-linejoin="round" ed:parentid="430"/>
    <path ed:tosuperid="442" stroke-linecap="round" fill="none" d="M13.5,-20.3C-1.8,-20.3,5.1,20.3,-13.5,20.3" id="443" transform="matrix(1,0,0,1,848,1683)" stroke="#696969" stroke-linejoin="round" ed:parentid="430"/>
    <path ed:tosuperid="444" stroke-linecap="round" fill="none" d="M13.5,2.5C2.1,2.5,-4,-2.5,-13.5,-2.5" id="445" transform="matrix(1,0,0,1,848,1750)" stroke="#696969" stroke-linejoin="round" ed:parentid="432"/>
    <path ed:tosuperid="446" stroke-linecap="round" fill="none" d="M13.5,-11C0.2,-11,0.5,11,-13.5,11" id="447" transform="matrix(1,0,0,1,848,1763)" stroke="#696969" stroke-linejoin="round" ed:parentid="432"/>
    <path ed:tosuperid="448" stroke-linecap="round" fill="none" d="M13.5,11C0.2,11,0.5,-11,-13.5,-11" id="449" transform="matrix(1,0,0,1,836,1829)" stroke="#696969" stroke-linejoin="round" ed:parentid="434"/>
    <path ed:tosuperid="450" stroke-linecap="round" fill="none" d="M13.5,-19.5C-1.7,-19.5,4.8,19.5,-13.5,19.5" id="451" transform="matrix(1,0,0,1,836,1860)" stroke="#696969" stroke-linejoin="round" ed:parentid="434"/>
    <path ed:tosuperid="452" stroke-linecap="round" fill="none" d="M-3.7,-44L-3.7,44L-13.5,44" id="453" transform="matrix(1,0,0,1,985,2021)" stroke="#696969" stroke-linejoin="round" ed:parentid="109"/>
    <path ed:tosuperid="454" stroke-linecap="round" fill="none" d="M13.5,70.6C-5.4,70.6,13.5,-70.6,-13.5,-70.6" id="455" transform="matrix(1,0,0,1,757,1994)" stroke="#696969" stroke-linejoin="round" ed:parentid="452"/>
    <path ed:tosuperid="456" stroke-linecap="round" fill="none" d="M13.5,57.9C-5.4,57.9,13.5,-57.9,-13.5,-57.9" id="457" transform="matrix(1,0,0,1,757,2007)" stroke="#696969" stroke-linejoin="round" ed:parentid="452"/>
    <path ed:tosuperid="458" stroke-linecap="round" fill="none" d="M13.5,-22.1C-2.2,-22.1,5.9,22.1,-13.5,22.1" id="459" transform="matrix(1,0,0,1,757,2087)" stroke="#696969" stroke-linejoin="round" ed:parentid="452"/>
    <path ed:tosuperid="460" stroke-linecap="round" fill="none" d="M13.5,62.5C-5.4,62.5,13.5,-62.5,-13.5,-62.5" id="461" transform="matrix(1,0,0,1,541,2046)" stroke="#696969" stroke-linejoin="round" ed:parentid="458"/>
    <path ed:tosuperid="462" stroke-linecap="round" fill="none" d="M13.5,44.3C-5.1,44.3,12.7,-44.3,-13.5,-44.3" id="463" transform="matrix(1,0,0,1,541,2065)" stroke="#696969" stroke-linejoin="round" ed:parentid="458"/>
    <path ed:tosuperid="464" stroke-linecap="round" fill="none" d="M13.5,22.3C-2.2,22.3,6,-22.3,-13.5,-22.3" id="465" transform="matrix(1,0,0,1,541,2087)" stroke="#696969" stroke-linejoin="round" ed:parentid="458"/>
    <path ed:tosuperid="466" stroke-linecap="round" fill="none" d="M13.5,3C2,3,-3.8,-3,-13.5,-3" id="467" transform="matrix(1,0,0,1,541,2106)" stroke="#696969" stroke-linejoin="round" ed:parentid="458"/>
    <path ed:tosuperid="468" stroke-linecap="round" fill="none" d="M13.5,-26.5C-2.9,-26.5,7.8,26.5,-13.5,26.5" id="469" transform="matrix(1,0,0,1,541,2135)" stroke="#696969" stroke-linejoin="round" ed:parentid="458"/>
    <path ed:tosuperid="470" stroke-linecap="round" fill="none" d="M13.5,-57C-5.4,-57,13.5,57,-13.5,57" id="471" transform="matrix(1,0,0,1,541,2166)" stroke="#696969" stroke-linejoin="round" ed:parentid="458"/>
    <path ed:tosuperid="472" stroke-linecap="round" fill="none" d="M-3.7,-179.8L-3.7,179.8L-13.5,179.8" id="473" transform="matrix(1,0,0,1,985,2156)" stroke="#696969" stroke-linejoin="round" ed:parentid="109"/>
    <path ed:tosuperid="474" stroke-linecap="round" fill="none" d="M13.5,36.4C-4.4,36.4,11.1,-36.4,-13.5,-36.4" id="475" transform="matrix(1,0,0,1,763,2300)" stroke="#696969" stroke-linejoin="round" ed:parentid="472"/>
    <path ed:tosuperid="476" stroke-linecap="round" fill="none" d="M13.5,5.9C1.3,5.9,-2.2,-5.9,-13.5,-5.9" id="477" transform="matrix(1,0,0,1,763,2330)" stroke="#696969" stroke-linejoin="round" ed:parentid="472"/>
    <path ed:tosuperid="478" stroke-linecap="round" fill="none" d="M13.5,-7.6C0.9,-7.6,-1.2,7.6,-13.5,7.6" id="479" transform="matrix(1,0,0,1,763,2344)" stroke="#696969" stroke-linejoin="round" ed:parentid="472"/>
    <path ed:tosuperid="480" stroke-linecap="round" fill="none" d="M13.5,-21.1C-2,-21.1,5.5,21.1,-13.5,21.1" id="481" transform="matrix(1,0,0,1,763,2357)" stroke="#696969" stroke-linejoin="round" ed:parentid="472"/>
    <path ed:tosuperid="482" stroke-linecap="round" fill="none" d="M13.5,-43.1C-5,-43.1,12.6,43.1,-13.5,43.1" id="483" transform="matrix(1,0,0,1,763,2379)" stroke="#696969" stroke-linejoin="round" ed:parentid="472"/>
    <g ed:width="364.094" ed:height="84" ed:layout="map" id="101" transform="matrix(1,0,0,1,1195,2481)" ed:topictype="mainidea">
        <path fill="#435fbc" d="M4,0L360.1,0C362.8,0,364.1,1.3,364.1,4L364.1,80C364.1,82.7,362.8,84,360.1,84L4,84C1.3,84,0,82.7,0,80L0,4C0,1.3,1.3,0,4,0z" stroke-width="3" stroke="#435fbc" stroke-linejoin="round"/>
        <text class="st27">
            <tspan y="37" x="91" style="white-space:pre">设计模式之美-结构型</tspan>
            <tspan y="64" x="22" style="white-space:pre">（解决“类或对象的组合或组装”问题）</tspan>
        </text>
    </g>
    <g ed:width="123.484" ed:height="35" ed:layout="rightmap" id="103" transform="matrix(1,0,0,1,1622,880)" ed:parentid="101">
        <path fill="#00b050" d="M4,0L119.5,0C122.2,0,123.5,1.3,123.5,4L123.5,31C123.5,33.7,122.2,35,119.5,35L4,35C1.3,35,0,33.7,0,31L0,4C0,1.3,1.3,0,4,0z" stroke="#ebecf3" stroke-linejoin="round"/>
        <text class="st28">
            <tspan y="24" x="18" style="white-space:pre">5、代理模式</tspan>
        </text>
    </g>
    <g ed:width="123.484" ed:height="35" ed:layout="rightmap" id="104" transform="matrix(1,0,0,1,1622,2198)" ed:parentid="101">
        <path fill="#00b050" d="M4,0L119.5,0C122.2,0,123.5,1.3,123.5,4L123.5,31C123.5,33.7,122.2,35,119.5,35L4,35C1.3,35,0,33.7,0,31L0,4C0,1.3,1.3,0,4,0z" stroke="#ebecf3" stroke-linejoin="round"/>
        <text class="st28">
            <tspan y="24" x="18" style="white-space:pre">6、桥接模式</tspan>
        </text>
    </g>
    <g ed:width="138.484" ed:height="35" ed:layout="rightmap" id="105" transform="matrix(1,0,0,1,1622,3151)" ed:parentid="101">
        <path fill="#00b050" d="M4,0L134.5,0C137.2,0,138.5,1.3,138.5,4L138.5,31C138.5,33.7,137.2,35,134.5,35L4,35C1.3,35,0,33.7,0,31L0,4C0,1.3,1.3,0,4,0z" stroke="#ebecf3" stroke-linejoin="round"/>
        <text class="st28">
            <tspan y="24" x="18" style="white-space:pre">7、装饰器模式</tspan>
        </text>
    </g>
    <g ed:width="138.484" ed:height="35" ed:layout="rightmap" id="106" transform="matrix(1,0,0,1,1622,4351)" ed:parentid="101">
        <path fill="#00b050" d="M4,0L134.5,0C137.2,0,138.5,1.3,138.5,4L138.5,31C138.5,33.7,137.2,35,134.5,35L4,35C1.3,35,0,33.7,0,31L0,4C0,1.3,1.3,0,4,0z" stroke="#ebecf3" stroke-linejoin="round"/>
        <text class="st28">
            <tspan y="24" x="18" style="white-space:pre">8、适配器模式</tspan>
        </text>
    </g>
    <g ed:width="129" ed:height="56" ed:layout="leftmap" id="107" transform="matrix(1,0,0,1,1003,3333)" ed:parentid="101">
        <path fill="#00b050" d="M4,0L125,0C127.7,0,129,1.3,129,4L129,52C129,54.7,127.7,56,125,56L4,56C1.3,56,0,54.7,0,52L0,4C0,1.3,1.3,0,4,0z" stroke="#ebecf3" stroke-linejoin="round"/>
        <text class="st28">
            <tspan y="24" x="18" style="white-space:pre">9、门面模式</tspan>
            <tspan y="45" x="18" style="white-space:pre">（外观模式）</tspan>
        </text>
    </g>
    <g ed:width="132.969" ed:height="35" ed:layout="leftmap" id="108" transform="matrix(1,0,0,1,999,2797)" ed:parentid="101">
        <path fill="#00b050" d="M4,0L129,0C131.7,0,133,1.3,133,4L133,31C133,33.7,131.7,35,129,35L4,35C1.3,35,0,33.7,0,31L0,4C0,1.3,1.3,0,4,0z" stroke="#ebecf3" stroke-linejoin="round"/>
        <text class="st28">
            <tspan y="24" x="18" style="white-space:pre">10、组合模式</tspan>
        </text>
    </g>
    <g ed:width="132.969" ed:height="35" ed:layout="leftmap" id="109" transform="matrix(1,0,0,1,999,1959)" ed:parentid="101">
        <path fill="#00b050" d="M4,0L129,0C131.7,0,133,1.3,133,4L133,31C133,33.7,131.7,35,129,35L4,35C1.3,35,0,33.7,0,31L0,4C0,1.3,1.3,0,4,0z" stroke="#ebecf3" stroke-linejoin="round"/>
        <text class="st28">
            <tspan y="24" x="18" style="white-space:pre">11、享元模式</tspan>
        </text>
    </g>
    <g ed:width="347.5" ed:height="56" ed:layout="map" id="125" transform="matrix(1,0,0,1,1151,2047)" ed:topictype="floating">
        <path fill="#ffffff" d="M4,0L343.5,0C346.2,0,347.5,1.3,347.5,4L347.5,52C347.5,54.7,346.2,56,343.5,56L4,56C1.3,56,0,54.7,0,52L0,4C0,1.3,1.3,0,4,0z" stroke="#f38590" stroke-linejoin="round"/>
        <text class="st29">
            <tspan y="24" x="18" style="white-space:pre">总结了一些类或对象组合在一起的经典结构，</tspan>
            <tspan y="45" x="18" style="white-space:pre">这些经典的结构可以解决特定应用场景的问题</tspan>
        </text>
    </g>
    <g ed:width="450" ed:height="20.5" ed:layout="rightmap" id="126" transform="matrix(1,0,0,1,1772,21)" ed:parentid="103">
        <path fill="#ffffff" d="M0,0L450,0L450,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L450,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">在不改变原始类（被代理类）代码的情况下，通过引入代理类来给原始类附加功能</tspan>
        </text>
    </g>
    <g ed:width="189.797" ed:height="54.5" ed:layout="rightmap" id="128" transform="matrix(1,0,0,1,1772,300)" ed:parentid="103">
        <path fill="#ffffff" d="M0,0L189.8,0L189.8,54.5L0,54.5L0,0z"/>
        <path fill="none" d="M0,54.5L189.8,54.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.6" x="7" style="white-space:pre">静态代理</tspan>
            <tspan y="31.6" x="7" style="white-space:pre">原始类和代理类 实现相同的接口</tspan>
            <tspan y="48.6" x="7" style="white-space:pre">（自己写原始类）</tspan>
        </text>
    </g>
    <g ed:width="138" ed:height="20.5" ed:layout="rightmap" id="130" transform="matrix(1,0,0,1,1989,153)" ed:parentid="128">
        <path fill="#ffffff" d="M0,0L138,0L138,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L138,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">原始类只负责业务功能</tspan>
        </text>
    </g>
    <g ed:width="270" ed:height="37.5" ed:layout="rightmap" id="132" transform="matrix(1,0,0,1,1989,405)" ed:parentid="128">
        <path fill="#ffffff" d="M0,0L270,0L270,37.5L0,37.5L0,0z"/>
        <path fill="none" d="M0,37.5L270,37.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.6" x="8" style="white-space:pre">代理类负责在业务执行前后附加其他逻辑代码</tspan>
            <tspan y="31.6" x="8" style="white-space:pre">，并通过委托的方式调用原始类来执行业务代码</tspan>
        </text>
    </g>
    <g ed:width="234" ed:height="54.5" ed:layout="rightmap" id="134" transform="matrix(1,0,0,1,1772,741)" ed:parentid="103">
        <path fill="#ffffff" d="M0,0L234,0L234,54.5L0,54.5L0,0z"/>
        <path fill="none" d="M0,54.5L234,54.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.6" x="8" style="white-space:pre">静态代理</tspan>
            <tspan y="31.6" x="8" style="white-space:pre">让代理类继承原始类，然后扩展附加功能</tspan>
            <tspan y="48.6" x="8" style="white-space:pre">（别人写的原始类）</tspan>
        </text>
    </g>
    <g ed:width="162" ed:height="37.5" ed:layout="rightmap" id="136" transform="matrix(1,0,0,1,1772,1271)" ed:parentid="103">
        <path fill="#ffffff" d="M0,0L162,0L162,37.5L0,37.5L0,0z"/>
        <path fill="none" d="M0,37.5L162,37.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.6" x="8" style="white-space:pre">动态代理</tspan>
            <tspan y="31.6" x="8" style="white-space:pre">（需要代理的原始类太多）</tspan>
        </text>
    </g>
    <g ed:width="334.266" ed:height="64" ed:layout="rightmap" id="138" transform="matrix(1,0,0,1,2154,48)" ed:parentid="130">
        <path fill="#ebebeb" d="M0,0L334.3,0L334.3,64L0,64L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st31">
            <tspan y="13" x="9" class="st32" style="white-space:pre">public </tspan>
            <tspan class="st33" style="white-space:pre">interface</tspan>
            <tspan class="st32" style="white-space:pre"> </tspan>
            <tspan style="white-space:pre">IUserController</tspan>
            <tspan class="st32" style="white-space:pre"> { </tspan>
            <tspan y="28" x="9" class="st32" style="white-space:pre">    UserVo login(String telephone, String password); </tspan>
            <tspan y="43" x="9" class="st32" style="white-space:pre">    UserVo register(String telephone, String password);</tspan>
            <tspan y="58" x="9" class="st32" style="white-space:pre"> }</tspan>
        </text>
    </g>
    <g ed:width="389.047" ed:height="160" ed:layout="rightmap" id="140" transform="matrix(1,0,0,1,2154,119)" ed:parentid="130">
        <path fill="#ebebeb" d="M0,0L389,0L389,160L0,160L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st34">
            <tspan y="13" x="9" class="st32" style="white-space:pre">public class </tspan>
            <tspan class="st35" style="white-space:pre">UserController</tspan>
            <tspan class="st32" style="white-space:pre"> </tspan>
            <tspan style="white-space:pre">implements</tspan>
            <tspan class="st32" style="white-space:pre"> IUserController { </tspan>
            <tspan y="30" x="9" class="st32" style="white-space:pre">    //...省略其他属性和方法... </tspan>
            <tspan y="45" x="9" class="st32" style="white-space:pre">    @Override </tspan>
            <tspan y="60" x="9" class="st32" style="white-space:pre">    public UserVo login(String telephone, String password) { </tspan>
            <tspan y="77" x="9" class="st32" style="white-space:pre">        //...省略login逻辑... </tspan>
            <tspan y="94" x="9" class="st32" style="white-space:pre">        //...返回UserVo数据... </tspan>
            <tspan y="109" x="9" class="st32" style="white-space:pre">    }</tspan>
            <tspan y="124" x="9" class="st32" style="white-space:pre">    @Override </tspan>
            <tspan y="139" x="9" class="st32" style="white-space:pre">    public UserVo register(String telephone, String password) { } </tspan>
            <tspan y="154" x="9" class="st32" style="white-space:pre">}</tspan>
        </text>
    </g>
    <g ed:width="445.234" ed:height="278" ed:layout="rightmap" id="142" transform="matrix(1,0,0,1,2286,285)" ed:parentid="132">
        <path fill="#ebebeb" d="M0,0L445.2,0L445.2,278L0,278L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st34">
            <tspan y="13" x="9" class="st32" style="white-space:pre">public class </tspan>
            <tspan class="st35" style="white-space:pre">UserControllerProxy</tspan>
            <tspan class="st32" style="white-space:pre"> </tspan>
            <tspan style="white-space:pre">implements</tspan>
            <tspan class="st32" style="white-space:pre"> IUserController {</tspan>
            <tspan y="28" x="9" class="st32" style="white-space:pre">    private MetricsCollector metricsCollector; </tspan>
            <tspan y="43" x="9" class="st32" style="white-space:pre">    private </tspan>
            <tspan class="st35" style="white-space:pre">UserController</tspan>
            <tspan class="st32" style="white-space:pre"> userController; </tspan>
            <tspan y="58" x="9" class="st32" style="white-space:pre">    public UserControllerProxy(</tspan>
            <tspan class="st35" style="white-space:pre">UserController</tspan>
            <tspan class="st32" style="white-space:pre"> userController) { </tspan>
            <tspan y="73" x="9" class="st32" style="white-space:pre">        this.userController = userController; </tspan>
            <tspan y="88" x="9" class="st32" style="white-space:pre">        this.metricsCollector = new MetricsCollector(); </tspan>
            <tspan y="103" x="9" class="st32" style="white-space:pre">    }</tspan>
            <tspan y="118" x="9" class="st32" style="white-space:pre">    @Override </tspan>
            <tspan y="133" x="9" class="st32" style="white-space:pre">    public UserVo login(String telephone, String password) { </tspan>
            <tspan y="148" x="9" class="st32" style="white-space:pre">        long startTimestamp = System.currentTimeMillis(); </tspan>
            <tspan y="165" x="9" class="st32" style="white-space:pre">        // 委托</tspan>
            <tspan y="180" x="9" class="st32" style="white-space:pre">        UserVo userVo = </tspan>
            <tspan class="st35" style="white-space:pre">userController</tspan>
            <tspan class="st32" style="white-space:pre">.login(telephone, password); </tspan>
            <tspan y="195" x="9" class="st32" style="white-space:pre">        long endTimeStamp = System.currentTimeMillis(); </tspan>
            <tspan y="212" x="9" class="st32" style="white-space:pre">        /...省略监控代码....</tspan>
            <tspan y="227" x="9" class="st32" style="white-space:pre">        return userVo; </tspan>
            <tspan y="242" x="9" class="st32" style="white-space:pre">    }</tspan>
            <tspan y="257" x="9" class="st32" style="white-space:pre">    @Override public UserVo register(String telephone, String password) {}</tspan>
            <tspan y="272" x="9" class="st32" style="white-space:pre">}</tspan>
        </text>
    </g>
    <g ed:width="138" ed:height="20.5" ed:layout="rightmap" id="144" transform="matrix(1,0,0,1,1989,577)" ed:parentid="128">
        <path fill="#ffffff" d="M0,0L138,0L138,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L138,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">基于接口而非实现编程</tspan>
        </text>
    </g>
    <g ed:width="484.297" ed:height="36" ed:layout="rightmap" id="146" transform="matrix(1,0,0,1,2154,570)" ed:parentid="144">
        <path fill="#ebebeb" d="M0,0L484.3,0L484.3,36L0,36L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st31">
            <tspan y="15" x="9" class="st32" style="white-space:pre">//将UserController类对象替换为UserControllerProxy类对象，不需要改动太多代码</tspan>
            <tspan y="30" x="9" style="white-space:pre">IUserController</tspan>
            <tspan class="st32" style="white-space:pre"> userController = new </tspan>
            <tspan style="white-space:pre">UserControllerProxy</tspan>
            <tspan class="st32" style="white-space:pre">(new </tspan>
            <tspan style="white-space:pre">UserController</tspan>
            <tspan class="st32" style="white-space:pre">())</tspan>
        </text>
    </g>
    <g ed:width="381.359" ed:height="312" ed:layout="rightmap" id="148" transform="matrix(1,0,0,1,2033,612)" ed:parentid="134">
        <path fill="#ebebeb" d="M0,0L381.4,0L381.4,312L0,312L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st31">
            <tspan y="13" x="9" class="st32" style="white-space:pre">public class UserControllerProxy </tspan>
            <tspan class="st33" style="white-space:pre">extends</tspan>
            <tspan class="st32" style="white-space:pre"> </tspan>
            <tspan style="white-space:pre">UserController</tspan>
            <tspan class="st32" style="white-space:pre"> { </tspan>
            <tspan y="28" x="9" class="st32" style="white-space:pre">    private MetricsCollector metricsCollector; </tspan>
            <tspan y="43" x="9" class="st32" style="white-space:pre">    public UserControllerProxy() { </tspan>
            <tspan y="58" x="9" class="st32" style="white-space:pre">        this.metricsCollector = new MetricsCollector(); </tspan>
            <tspan y="73" x="9" class="st32" style="white-space:pre">    }</tspan>
            <tspan y="88" x="9" class="st32" style="white-space:pre">    public UserVo login(String telephone, String password) { </tspan>
            <tspan y="103" x="9" class="st32" style="white-space:pre">        long startTimestamp = System.currentTimeMillis(); </tspan>
            <tspan y="118" x="9" class="st32" style="white-space:pre">        UserVo userVo = </tspan>
            <tspan style="white-space:pre">super</tspan>
            <tspan class="st32" style="white-space:pre">.login(telephone, password); </tspan>
            <tspan y="135" x="9" class="st32" style="white-space:pre">        //...省略代码...</tspan>
            <tspan y="150" x="9" class="st32" style="white-space:pre">        return userVo; </tspan>
            <tspan y="165" x="9" class="st32" style="white-space:pre">    }</tspan>
            <tspan y="180" x="9" class="st32" style="white-space:pre">    public UserVo register(String telephone, String password) { </tspan>
            <tspan y="197" x="9" class="st32" style="white-space:pre">        // ...省略代码...</tspan>
            <tspan y="212" x="9" class="st32" style="white-space:pre">        UserVo userVo = </tspan>
            <tspan style="white-space:pre">super</tspan>
            <tspan class="st32" style="white-space:pre">.register(telephone, password); </tspan>
            <tspan y="229" x="9" class="st32" style="white-space:pre">        //...省略代码...</tspan>
            <tspan y="244" x="9" class="st32" style="white-space:pre">    }</tspan>
            <tspan y="259" x="9" class="st32" style="white-space:pre">}</tspan>
            <tspan y="291" x="9" class="st32" style="white-space:pre">//UserControllerProxy使用举例</tspan>
            <tspan y="306" x="9" style="white-space:pre">UserController</tspan>
            <tspan class="st32" style="white-space:pre"> userController = new </tspan>
            <tspan style="white-space:pre">UserControllerProxy</tspan>
            <tspan class="st32" style="white-space:pre">();</tspan>
        </text>
    </g>
    <g ed:width="678" ed:height="20.5" ed:layout="rightmap" id="150" transform="matrix(1,0,0,1,1961,931)" ed:parentid="136">
        <path fill="#ffffff" d="M0,0L678,0L678,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L678,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">不事先为每个原始类编写代理类，而是在运行的时候，动态地创建原始类对应的代理类，然后在系统中用代理类替换掉原始类</tspan>
        </text>
    </g>
    <g ed:width="240.766" ed:height="20.5" ed:layout="rightmap" id="152" transform="matrix(1,0,0,1,1961,958)" ed:parentid="136">
        <path fill="#ffffff" d="M0,0L240.8,0L240.8,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L240.8,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">动态代理底层依赖的就是 Java 的反射语法</tspan>
        </text>
    </g>
    <g ed:width="579.0940000000001" ed:height="604" ed:layout="rightmap" id="154" transform="matrix(1,0,0,1,1961,1046)" ed:parentid="136">
        <path fill="#ebebeb" d="M0,0L579.1,0L579.1,604L0,604L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st36">
            <tspan y="13" x="9" class="st32" style="white-space:pre">public class </tspan>
            <tspan class="st35" style="white-space:pre">MetricsCollectorProxy</tspan>
            <tspan class="st32" style="white-space:pre"> {</tspan>
            <tspan y="43" x="9" class="st32" style="white-space:pre">    private MetricsCollector metricsCollector;</tspan>
            <tspan y="73" x="9" class="st32" style="white-space:pre">    public MetricsCollectorProxy(MetricsCollector metricsCollector) {</tspan>
            <tspan y="88" x="9" class="st32" style="white-space:pre">        this.metricsCollector = new MetricsCollector();</tspan>
            <tspan y="103" x="9" class="st32" style="white-space:pre">    }</tspan>
            <tspan y="133" x="9" class="st32" style="white-space:pre">    public Object </tspan>
            <tspan class="st35" style="white-space:pre">createProxy</tspan>
            <tspan class="st32" style="white-space:pre">(Object proxiedObject) {</tspan>
            <tspan y="148" x="9" class="st32" style="white-space:pre">        ClassLoader classLoader = proxiedObject.getClass().getClassLoader();</tspan>
            <tspan y="163" x="9" class="st32" style="white-space:pre">        Class&lt;?>[] interfaces = proxiedObject.getClass().getInterfaces();</tspan>
            <tspan y="178" x="9" class="st32" style="white-space:pre">        DynamicProxyHandler handler = new DynamicProxyHandler(proxiedObject);</tspan>
            <tspan y="193" x="9" class="st32" style="white-space:pre">        return Proxy.newProxyInstance(classLoader, interfaces,handler);</tspan>
            <tspan y="208" x="9" class="st32" style="white-space:pre">    }</tspan>
            <tspan y="238" x="9" class="st32" style="white-space:pre">    private class </tspan>
            <tspan class="st35" style="white-space:pre">DynamicProxyHandler</tspan>
            <tspan class="st32" style="white-space:pre"> </tspan>
            <tspan class="st33" style="white-space:pre">implements</tspan>
            <tspan class="st32" style="white-space:pre"> </tspan>
            <tspan class="st35" style="white-space:pre">InvocationHandler</tspan>
            <tspan class="st32" style="white-space:pre"> {</tspan>
            <tspan y="253" x="9" class="st32" style="white-space:pre">        private Object proxiedObject;</tspan>
            <tspan y="283" x="9" class="st32" style="white-space:pre">        public DynamicProxyHandler(Object proxiedObject) {</tspan>
            <tspan y="298" x="9" class="st32" style="white-space:pre">            this.proxiedObject = proxiedObject;</tspan>
            <tspan y="313" x="9" class="st32" style="white-space:pre">        }</tspan>
            <tspan y="343" x="9" class="st32" style="white-space:pre">        @Override</tspan>
            <tspan y="358" x="9" class="st32" style="white-space:pre">        public Object </tspan>
            <tspan class="st35" style="white-space:pre">invoke</tspan>
            <tspan class="st32" style="white-space:pre">(Object proxy, Method method, Object[] args) throws Throwable {</tspan>
            <tspan y="373" x="9" class="st32" style="white-space:pre">            long starttimestamp = System.currentTimeMillis();</tspan>
            <tspan y="388" x="9" class="st32" style="white-space:pre">            </tspan>
            <tspan class="st35" style="white-space:pre">Object result = method.invoke(proxiedObject, args);</tspan>
            <tspan y="403" x="9" class="st32" style="white-space:pre">            long endTimeStamp = System.currentTimeMillis();</tspan>
            <tspan y="418" x="9" class="st32" style="white-space:pre">            String apiName = proxiedObject.getClass().getName() + ":" + method.getName();</tspan>
            <tspan y="433" x="9" class="st32" style="white-space:pre">            RegisterInfo registerInfo = new RegisterInfo(apiName,startTimestamp,endTimeStamp);</tspan>
            <tspan y="448" x="9" class="st32" style="white-space:pre">            </tspan>
            <tspan class="st35" style="white-space:pre">metricsCollector</tspan>
            <tspan class="st32" style="white-space:pre">.</tspan>
            <tspan class="st35" style="white-space:pre">register</tspan>
            <tspan class="st32" style="white-space:pre">(registerInfo);</tspan>
            <tspan y="463" x="9" class="st32" style="white-space:pre">            return result;</tspan>
            <tspan y="478" x="9" class="st32" style="white-space:pre">        }</tspan>
            <tspan y="493" x="9" class="st32" style="white-space:pre">    }</tspan>
            <tspan y="523" x="9" class="st32" style="white-space:pre">    public static void </tspan>
            <tspan class="st35" style="white-space:pre">main</tspan>
            <tspan class="st32" style="white-space:pre">(String[] args) {</tspan>
            <tspan y="538" x="9" class="st32" style="white-space:pre">        MetricsCollectorProxy proxy = new </tspan>
            <tspan class="st35" style="white-space:pre">MetricsCollectorProxy</tspan>
            <tspan class="st32" style="white-space:pre">(new </tspan>
            <tspan class="st35" style="white-space:pre">MetricsCollector</tspan>
            <tspan class="st32" style="white-space:pre">());</tspan>
            <tspan y="553" x="9" class="st32" style="white-space:pre">        IUserController userController = (IUserController) </tspan>
            <tspan style="white-space:pre">proxy</tspan>
            <tspan class="st32" style="white-space:pre">.</tspan>
            <tspan style="white-space:pre">createProxy</tspan>
            <tspan class="st32" style="white-space:pre">(new UserController());</tspan>
            <tspan y="568" x="9" class="st32" style="white-space:pre">        System.out.println(userController.login());</tspan>
            <tspan y="583" x="9" class="st32" style="white-space:pre">    }</tspan>
            <tspan y="598" x="9" class="st32" style="white-space:pre">}</tspan>
        </text>
    </g>
    <g ed:width="279.078" ed:height="20.5" ed:layout="rightmap" id="156" transform="matrix(1,0,0,1,1961,1002)" ed:parentid="136">
        <path fill="#ffffff" d="M0,0L279.1,0L279.1,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L279.1,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="7" style="white-space:pre">Spring AOP 底层的实现原理就是基于动态代理。</tspan>
        </text>
    </g>
    <g ed:width="558" ed:height="54.5" ed:layout="rightmap" id="158" transform="matrix(1,0,0,1,2267,985)" ed:parentid="156">
        <path fill="#ffffff" d="M0,0L558,0L558,54.5L0,54.5L0,0z"/>
        <path fill="none" d="M0,54.5L558,54.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.6" x="8" style="white-space:pre">用户配置好需要给哪些类创建代理，并定义好在执行原始类的业务代码前后执行哪些附加功能。</tspan>
            <tspan y="31.6" x="8" style="white-space:pre">Spring 为这些类创建动态代理对象，并在 JVM 中替代原始类对象。</tspan>
            <tspan y="48.6" x="8" style="white-space:pre">原本在代码中执行的原始类的方法，被换作执行代理类的方法，实现了给原始类添加附加功能的目的。</tspan>
        </text>
    </g>
    <g ed:width="126" ed:height="20.5" ed:layout="rightmap" id="160" transform="matrix(1,0,0,1,1772,1705)" ed:parentid="103">
        <path fill="#ffffff" d="M0,0L126,0L126,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L126,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">代理模式的应用场景</tspan>
        </text>
    </g>
    <g ed:width="189.172" ed:height="20.5" ed:layout="rightmap" id="162" transform="matrix(1,0,0,1,1925,1670)" ed:parentid="160">
        <path fill="#ffffff" d="M0,0L189.2,0L189.2,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L189.2,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="7" style="white-space:pre">1. 业务系统的非功能性需求开发</tspan>
        </text>
    </g>
    <g ed:width="55.6719" ed:height="18.5" ed:layout="rightmap" id="164" transform="matrix(1,0,0,1,1925,1711)" ed:parentid="160">
        <path fill="#ffffff" d="M0,0L55.7,0L55.7,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L55.7,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="12.7" x="7" style="white-space:pre">2. RPC</tspan>
        </text>
    </g>
    <g ed:width="474" ed:height="20.5" ed:layout="rightmap" id="166" transform="matrix(1,0,0,1,2141,1656)" ed:parentid="162">
        <path fill="#ffffff" d="M0,0L474,0L474,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L474,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">在业务系统中开发一些非功能性需求：监控、统计、鉴权、限流、事务、幂等、日志。</tspan>
        </text>
    </g>
    <g ed:width="294.875" ed:height="20.5" ed:layout="rightmap" id="168" transform="matrix(1,0,0,1,2141,1683)" ed:parentid="162">
        <path fill="#ffffff" d="M0,0L294.9,0L294.9,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L294.9,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">这部分工作都是可以在 Spring AOP 切面中完成的。</tspan>
        </text>
    </g>
    <g ed:width="81.17189999999999" ed:height="20.5" ed:layout="rightmap" id="170" transform="matrix(1,0,0,1,1925,1746)" ed:parentid="160">
        <path fill="#ffffff" d="M0,0L81.2,0L81.2,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L81.2,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="7" style="white-space:pre">3. 懒加载：</tspan>
        </text>
    </g>
    <g ed:width="514" ed:height="37.5" ed:layout="rightmap" id="172" transform="matrix(1,0,0,1,2033,1737)" ed:parentid="170">
        <path fill="#ffffff" d="M0,0L514,0L514,37.5L0,37.5L0,0z"/>
        <path fill="none" d="M0,37.5L514,37.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.6" x="8" style="white-space:pre">hibernate、mybatis实现懒加载，是基于动态代理思想实现的，对刚查询出来的对象做一个代</tspan>
            <tspan y="31.6" x="8" style="white-space:pre">理。然后去调用getX()方法的时候，再实际执行sql查询出来关联的数据。</tspan>
        </text>
    </g>
    <g ed:width="618" ed:height="20.5" ed:layout="rightmap" id="174" transform="matrix(1,0,0,1,2008,1710)" ed:parentid="164">
        <path fill="#ffffff" d="M0,0L618,0L618,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L618,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">在本地做一个远程服务的本地代理接口，然后对本地代理接口来调用，代理对象发送网络请求调用远程服务的接口</tspan>
        </text>
    </g>
    <g ed:width="439" ed:height="19" ed:layout="rightmap" id="176" transform="matrix(1,0,0,1,1105,2142)" ed:parentid="125">
        <path fill="#ffffff" d="M0,0L439,0L439,19L0,19L0,0z"/>
        <text class="st30">
            <tspan y="15" x="9" style="white-space:pre">代理模式：在不改变原始类代码的情况下，通过引入代理类来给原始类附加功能</tspan>
        </text>
    </g>
    <g ed:width="234" ed:height="20.5" ed:layout="rightmap" id="178" transform="matrix(1,0,0,1,1772,1808)" ed:parentid="104">
        <path fill="#ffffff" d="M0,0L234,0L234,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L234,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">将抽象和实现解耦，让它们可以独立变化</tspan>
        </text>
    </g>
    <g ed:width="73.6875" ed:height="20.5" ed:layout="rightmap" id="181" transform="matrix(1,0,0,1,1772,1870)" ed:parentid="104">
        <path fill="#ffffff" d="M0,0L73.7,0L73.7,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L73.7,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">JDBC 驱动</tspan>
        </text>
    </g>
    <g ed:width="155.219" ed:height="20.5" ed:layout="rightmap" id="183" transform="matrix(1,0,0,1,1873,1835)" ed:parentid="181">
        <path fill="#ffffff" d="M0,0L155.2,0L155.2,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L155.2,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">JDBC 本身就相当于“抽象”</tspan>
        </text>
    </g>
    <g ed:width="279.531" ed:height="20.5" ed:layout="rightmap" id="185" transform="matrix(1,0,0,1,2055,1835)" ed:parentid="183">
        <path fill="#ffffff" d="M0,0L279.5,0L279.5,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L279.5,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">跟具体的数据库无关的、被抽象出来的一套“类库”</tspan>
        </text>
    </g>
    <g ed:width="325.375" ed:height="20.5" ed:layout="rightmap" id="187" transform="matrix(1,0,0,1,1873,1862)" ed:parentid="181">
        <path fill="#ffffff" d="M0,0L325.4,0L325.4,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L325.4,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">具体的Driver（com.mysql.jdbc.Driver）就相当于“实现”</tspan>
        </text>
    </g>
    <g ed:width="183.531" ed:height="20.5" ed:layout="rightmap" id="189" transform="matrix(1,0,0,1,2225,1862)" ed:parentid="187">
        <path fill="#ffffff" d="M0,0L183.5,0L183.5,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L183.5,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="7" style="white-space:pre">跟具体数据库相关的一套“类库”</tspan>
        </text>
    </g>
    <g ed:width="376.625" ed:height="37.5" ed:layout="rightmap" id="191" transform="matrix(1,0,0,1,1873,1889)" ed:parentid="181">
        <path fill="#ffffff" d="M0,0L376.6,0L376.6,37.5L0,37.5L0,0z"/>
        <path fill="none" d="M0,37.5L376.6,37.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.6" x="8" style="white-space:pre">JDBC 和Driver 独立开发，通过对象之间的组合关系，组装在一起。</tspan>
            <tspan y="31.6" x="8" style="white-space:pre">JDBC 的所有逻辑操作，最终都委托给 Driver 来执行。</tspan>
        </text>
    </g>
    <g ed:width="390.734" ed:height="199" ed:layout="rightmap" id="193" transform="matrix(1,0,0,1,1865,1933)" ed:parentid="195">
        <path fill="#ebebeb" d="M0,0L390.7,0L390.7,199L0,199L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st31">
            <tspan y="13" x="9" class="st32" style="white-space:pre">public </tspan>
            <tspan class="st33" style="white-space:pre">interface</tspan>
            <tspan class="st32" style="white-space:pre"> </tspan>
            <tspan style="white-space:pre">IMessageSender</tspan>
            <tspan class="st32" style="white-space:pre"> {</tspan>
            <tspan y="28" x="9" class="st32" style="white-space:pre">    void sendMsg(String msg);</tspan>
            <tspan y="43" x="9" class="st32" style="white-space:pre">}</tspan>
            <tspan y="73" x="9" class="st32" style="white-space:pre">public class </tspan>
            <tspan style="white-space:pre">EmailMessageSender</tspan>
            <tspan class="st32" style="white-space:pre"> </tspan>
            <tspan class="st33" style="white-space:pre">implements</tspan>
            <tspan class="st32" style="white-space:pre"> </tspan>
            <tspan style="white-space:pre">IMessageSender</tspan>
            <tspan class="st32" style="white-space:pre"> {</tspan>
            <tspan y="88" x="9" class="st32" style="white-space:pre">    @Override</tspan>
            <tspan y="103" x="9" class="st32" style="white-space:pre">    public void sendMsg(String msg) {log.info("msg is " + msg);}</tspan>
            <tspan y="118" x="9" class="st32" style="white-space:pre">}</tspan>
            <tspan y="148" x="9" class="st32" style="white-space:pre">public class </tspan>
            <tspan style="white-space:pre">SmssMessageSender</tspan>
            <tspan class="st32" style="white-space:pre"> </tspan>
            <tspan class="st33" style="white-space:pre">implements</tspan>
            <tspan class="st32" style="white-space:pre"> </tspan>
            <tspan style="white-space:pre">IMessageSender</tspan>
            <tspan class="st32" style="white-space:pre"> {</tspan>
            <tspan y="163" x="9" class="st32" style="white-space:pre">    @Override</tspan>
            <tspan y="178" x="9" class="st32" style="white-space:pre">    public void sendMsg(String msg) {log.info( "msg is " + msg);}</tspan>
            <tspan y="193" x="9" class="st32" style="white-space:pre">}</tspan>
        </text>
    </g>
    <g ed:width="66" ed:height="20.5" ed:layout="rightmap" id="195" transform="matrix(1,0,0,1,1772,2268)" ed:parentid="104">
        <path fill="#ffffff" d="M0,0L66,0L66,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L66,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">代码实现</tspan>
        </text>
    </g>
    <g ed:width="468.406" ed:height="396" ed:layout="rightmap" id="197" transform="matrix(1,0,0,1,1865,2138)" ed:parentid="195">
        <path fill="#ebebeb" d="M0,0L468.4,0L468.4,396L0,396L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st36">
            <tspan y="13" x="9" class="st32" style="white-space:pre">public </tspan>
            <tspan class="st33" style="white-space:pre">abstract</tspan>
            <tspan class="st32" style="white-space:pre"> class </tspan>
            <tspan class="st35" style="white-space:pre">AbsNotification</tspan>
            <tspan class="st32" style="white-space:pre"> {</tspan>
            <tspan y="28" x="9" class="st32" style="white-space:pre">    private </tspan>
            <tspan class="st35" style="white-space:pre">IMessageSender</tspan>
            <tspan class="st32" style="white-space:pre"> mSender;</tspan>
            <tspan y="45" x="9" class="st32" style="white-space:pre">    //抽象化和实现化之间通过组合的方式来链接(桥接)</tspan>
            <tspan y="60" x="9" class="st32" style="white-space:pre">    public AbsNotification(IMessageSender sender) { this.mSender = sender;  }</tspan>
            <tspan y="90" x="9" class="st32" style="white-space:pre">    public void </tspan>
            <tspan style="white-space:pre">sendMsg</tspan>
            <tspan class="st32" style="white-space:pre">(String msg) {</tspan>
            <tspan y="105" x="9" class="st32" style="white-space:pre">        this.mSender.sendMsg(msg);</tspan>
            <tspan y="120" x="9" class="st32" style="white-space:pre">        doCustomConfig();</tspan>
            <tspan y="135" x="9" class="st32" style="white-space:pre">    }</tspan>
            <tspan y="165" x="9" class="st32" style="white-space:pre">    </tspan>
            <tspan class="st33" style="white-space:pre">abstract</tspan>
            <tspan class="st32" style="white-space:pre"> void doCustomConfig();</tspan>
            <tspan y="180" x="9" class="st32" style="white-space:pre">}</tspan>
            <tspan y="210" x="9" class="st32" style="white-space:pre">public class </tspan>
            <tspan class="st35" style="white-space:pre">SevereNotification</tspan>
            <tspan class="st32" style="white-space:pre"> </tspan>
            <tspan class="st33" style="white-space:pre">extends</tspan>
            <tspan class="st32" style="white-space:pre"> </tspan>
            <tspan class="st35" style="white-space:pre">AbsNotification</tspan>
            <tspan class="st32" style="white-space:pre"> {</tspan>
            <tspan y="225" x="9" class="st32" style="white-space:pre">    public SevereNotification(IMessageSender sender) {super(sender);}</tspan>
            <tspan y="255" x="9" class="st32" style="white-space:pre">    @Override</tspan>
            <tspan y="270" x="9" class="st32" style="white-space:pre">    void doCustomConfig() {     log.info("severe custom");}</tspan>
            <tspan y="285" x="9" class="st32" style="white-space:pre">}</tspan>
            <tspan y="315" x="9" class="st32" style="white-space:pre">public class </tspan>
            <tspan class="st35" style="white-space:pre">NormalNotification</tspan>
            <tspan class="st32" style="white-space:pre"> </tspan>
            <tspan class="st33" style="white-space:pre">extends</tspan>
            <tspan class="st32" style="white-space:pre"> </tspan>
            <tspan class="st35" style="white-space:pre">AbsNotification</tspan>
            <tspan class="st32" style="white-space:pre"> {</tspan>
            <tspan y="330" x="9" class="st32" style="white-space:pre">    public NormalNotification(IMessageSender sender) { super(sender);}</tspan>
            <tspan y="360" x="9" class="st32" style="white-space:pre">    @Override</tspan>
            <tspan y="375" x="9" class="st32" style="white-space:pre">    void doCustomConfig() { log.info("normal custom");}</tspan>
            <tspan y="390" x="9" class="st32" style="white-space:pre">}</tspan>
        </text>
    </g>
    <g ed:width="563.2190000000001" ed:height="83" ed:layout="rightmap" id="199" transform="matrix(1,0,0,1,1865,2541)" ed:parentid="195">
        <path fill="#ebebeb" d="M0,0L563.2,0L563.2,83L0,83L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st31">
            <tspan y="13" x="9" class="st32" style="white-space:pre">SevereNotification severeNotification = new </tspan>
            <tspan style="white-space:pre">SevereNotification</tspan>
            <tspan class="st32" style="white-space:pre">(new </tspan>
            <tspan style="white-space:pre">EmailMessageSender</tspan>
            <tspan class="st32" style="white-space:pre">());</tspan>
            <tspan y="30" x="9" class="st32" style="white-space:pre">severeNotification.sendMsg("严重崩溃,通过邮件发送");</tspan>
            <tspan y="60" x="9" class="st32" style="white-space:pre">NormalNotification normalNotification = new NormalNotification(new SmssMessageSender());</tspan>
            <tspan y="77" x="9" class="st32" style="white-space:pre">normalNotification.sendMsg("正常问题,通过短信发送");</tspan>
        </text>
    </g>
    <g ed:width="150" ed:height="20.5" ed:layout="rightmap" id="201" transform="matrix(1,0,0,1,1787,2657)" ed:parentid="105">
        <path fill="#ffffff" d="M0,0L150,0L150,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L150,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">对目标类的功能进行增强</tspan>
        </text>
    </g>
    <g ed:width="64.01560000000001" ed:height="18.5" ed:layout="rightmap" id="203" transform="matrix(1,0,0,1,1787,2896)" ed:parentid="105">
        <path fill="#ffffff" d="M0,0L64,0L64,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L64,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="12.7" x="7" style="white-space:pre">Java I/O</tspan>
        </text>
    </g>
    <g ed:width="54" ed:height="20.5" ed:layout="rightmap" id="205" transform="matrix(1,0,0,1,1878,2808)" ed:parentid="203">
        <path fill="#ffffff" d="M0,0L54,0L54,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L54,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">字节流</tspan>
        </text>
    </g>
    <g ed:width="54" ed:height="20.5" ed:layout="rightmap" id="207" transform="matrix(1,0,0,1,1878,3033)" ed:parentid="203">
        <path fill="#ffffff" d="M0,0L54,0L54,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L54,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">字符流</tspan>
        </text>
    </g>
    <g ed:width="88.70310000000001" ed:height="18.5" ed:layout="rightmap" id="209" transform="matrix(1,0,0,1,1959,2734)" ed:parentid="205">
        <path fill="#ffffff" d="M0,0L88.7,0L88.7,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L88.7,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="12.7" x="8" style="white-space:pre">InputStream</tspan>
        </text>
    </g>
    <g ed:width="99.04689999999999" ed:height="18.5" ed:layout="rightmap" id="211" transform="matrix(1,0,0,1,1959,2871)" ed:parentid="205">
        <path fill="#ffffff" d="M0,0L99,0L99,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L99,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="12.7" x="7" style="white-space:pre">OutputStream</tspan>
        </text>
    </g>
    <g ed:width="58" ed:height="18.5" ed:layout="rightmap" id="213" transform="matrix(1,0,0,1,1959,2984)" ed:parentid="207">
        <path fill="#ffffff" d="M0,0L58,0L58,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L58,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="12.7" x="8" style="white-space:pre">Reader</tspan>
        </text>
    </g>
    <g ed:width="52.7031" ed:height="18.5" ed:layout="rightmap" id="215" transform="matrix(1,0,0,1,1959,3071)" ed:parentid="207">
        <path fill="#ffffff" d="M0,0L52.7,0L52.7,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L52.7,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="12.7" x="8" style="white-space:pre">Writer</tspan>
        </text>
    </g>
    <g ed:width="108.734" ed:height="18.5" ed:layout="rightmap" id="217" transform="matrix(1,0,0,1,2075,2684)" ed:parentid="209">
        <path fill="#ffffff" d="M0,0L108.7,0L108.7,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L108.7,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="12.7" x="8" style="white-space:pre">FileInputStream</tspan>
        </text>
    </g>
    <g ed:width="118.125" ed:height="18.5" ed:layout="rightmap" id="219" transform="matrix(1,0,0,1,2075,2721)" ed:parentid="209">
        <path fill="#ffffff" d="M0,0L118.1,0L118.1,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L118.1,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="12.7" x="8" style="white-space:pre">FilterInputStream</tspan>
        </text>
    </g>
    <g ed:width="126.5" ed:height="18.5" ed:layout="rightmap" id="221" transform="matrix(1,0,0,1,2075,2759)" ed:parentid="209">
        <path fill="#ffffff" d="M0,0L126.5,0L126.5,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L126.5,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="12.7" x="8" style="white-space:pre">ObjectInputStream</tspan>
        </text>
    </g>
    <g ed:width="143.984" ed:height="18.5" ed:layout="rightmap" id="223" transform="matrix(1,0,0,1,2075,2784)" ed:parentid="209">
        <path fill="#ffffff" d="M0,0L144,0L144,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L144,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="12.7" x="8" style="white-space:pre">ByteArrayInputStream</tspan>
        </text>
    </g>
    <g ed:width="137.281" ed:height="18.5" ed:layout="rightmap" id="225" transform="matrix(1,0,0,1,2220,2709)" ed:parentid="219">
        <path fill="#ffffff" d="M0,0L137.3,0L137.3,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L137.3,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="12.7" x="7" style="white-space:pre">BufferedInputStream</tspan>
        </text>
    </g>
    <g ed:width="115.422" ed:height="18.5" ed:layout="rightmap" id="227" transform="matrix(1,0,0,1,2220,2734)" ed:parentid="219">
        <path fill="#ffffff" d="M0,0L115.4,0L115.4,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L115.4,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="12.7" x="7" style="white-space:pre">DataInputStream</tspan>
        </text>
    </g>
    <g ed:width="119.078" ed:height="18.5" ed:layout="rightmap" id="229" transform="matrix(1,0,0,1,2085,2809)" ed:parentid="211">
        <path fill="#ffffff" d="M0,0L119.1,0L119.1,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L119.1,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="12.7" x="8" style="white-space:pre">FileOutputStream</tspan>
        </text>
    </g>
    <g ed:width="128.469" ed:height="18.5" ed:layout="rightmap" id="231" transform="matrix(1,0,0,1,2085,2859)" ed:parentid="211">
        <path fill="#ffffff" d="M0,0L128.5,0L128.5,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L128.5,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="12.7" x="8" style="white-space:pre">FilterOutputStream</tspan>
        </text>
    </g>
    <g ed:width="136.844" ed:height="18.5" ed:layout="rightmap" id="233" transform="matrix(1,0,0,1,2085,2909)" ed:parentid="211">
        <path fill="#ffffff" d="M0,0L136.8,0L136.8,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L136.8,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="12.7" x="8" style="white-space:pre">ObjectOutputStream</tspan>
        </text>
    </g>
    <g ed:width="154.328" ed:height="18.5" ed:layout="rightmap" id="235" transform="matrix(1,0,0,1,2085,2934)" ed:parentid="211">
        <path fill="#ffffff" d="M0,0L154.3,0L154.3,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L154.3,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="12.7" x="8" style="white-space:pre">ByteArrayOutputStream</tspan>
        </text>
    </g>
    <g ed:width="147.625" ed:height="18.5" ed:layout="rightmap" id="237" transform="matrix(1,0,0,1,2241,2834)" ed:parentid="231">
        <path fill="#ffffff" d="M0,0L147.6,0L147.6,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L147.6,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="12.7" x="8" style="white-space:pre">BufferedOutputStream</tspan>
        </text>
    </g>
    <g ed:width="125.766" ed:height="18.5" ed:layout="rightmap" id="239" transform="matrix(1,0,0,1,2241,2859)" ed:parentid="231">
        <path fill="#ffffff" d="M0,0L125.8,0L125.8,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L125.8,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="12.7" x="7" style="white-space:pre">DataOutputStream</tspan>
        </text>
    </g>
    <g ed:width="85.26560000000001" ed:height="18.5" ed:layout="rightmap" id="241" transform="matrix(1,0,0,1,2241,2884)" ed:parentid="231">
        <path fill="#ffffff" d="M0,0L85.3,0L85.3,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L85.3,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="12.7" x="7" style="white-space:pre">PrintStream</tspan>
        </text>
    </g>
    <g ed:width="106.578" ed:height="18.5" ed:layout="rightmap" id="243" transform="matrix(1,0,0,1,2044,2959)" ed:parentid="213">
        <path fill="#ffffff" d="M0,0L106.6,0L106.6,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L106.6,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="12.7" x="8" style="white-space:pre">BufferedReader</tspan>
        </text>
    </g>
    <g ed:width="117.5" ed:height="18.5" ed:layout="rightmap" id="245" transform="matrix(1,0,0,1,2044,2984)" ed:parentid="213">
        <path fill="#ffffff" d="M0,0L117.5,0L117.5,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L117.5,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="12.7" x="8" style="white-space:pre">InputStreaReader</tspan>
        </text>
    </g>
    <g ed:width="92.2188" ed:height="18.5" ed:layout="rightmap" id="247" transform="matrix(1,0,0,1,2044,3009)" ed:parentid="213">
        <path fill="#ffffff" d="M0,0L92.2,0L92.2,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L92.2,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="12.7" x="8" style="white-space:pre">StringReader</tspan>
        </text>
    </g>
    <g ed:width="78.0313" ed:height="18.5" ed:layout="rightmap" id="249" transform="matrix(1,0,0,1,2189,2984)" ed:parentid="245">
        <path fill="#ffffff" d="M0,0L78,0L78,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L78,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="12.7" x="7" style="white-space:pre">FileReader</tspan>
        </text>
    </g>
    <g ed:width="101.281" ed:height="18.5" ed:layout="rightmap" id="252" transform="matrix(1,0,0,1,2039,3034)" ed:parentid="215">
        <path fill="#ffffff" d="M0,0L101.3,0L101.3,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L101.3,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="12.7" x="7" style="white-space:pre">BufferedWriter</tspan>
        </text>
    </g>
    <g ed:width="133.75" ed:height="18.5" ed:layout="rightmap" id="254" transform="matrix(1,0,0,1,2039,3059)" ed:parentid="215">
        <path fill="#ffffff" d="M0,0L133.8,0L133.8,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L133.8,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="12.7" x="8" style="white-space:pre">OutputStreamWriter</tspan>
        </text>
    </g>
    <g ed:width="79.625" ed:height="18.5" ed:layout="rightmap" id="256" transform="matrix(1,0,0,1,2039,3084)" ed:parentid="215">
        <path fill="#ffffff" d="M0,0L79.6,0L79.6,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L79.6,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="12.7" x="8" style="white-space:pre">PrintWriter</tspan>
        </text>
    </g>
    <g ed:width="86.92189999999999" ed:height="18.5" ed:layout="rightmap" id="258" transform="matrix(1,0,0,1,2039,3109)" ed:parentid="215">
        <path fill="#ffffff" d="M0,0L86.9,0L86.9,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L86.9,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="12.7" x="7" style="white-space:pre">StringWriter</tspan>
        </text>
    </g>
    <g ed:width="72.73439999999999" ed:height="18.5" ed:layout="rightmap" id="260" transform="matrix(1,0,0,1,2200,3059)" ed:parentid="254">
        <path fill="#ffffff" d="M0,0L72.7,0L72.7,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L72.7,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="12.7" x="8" style="white-space:pre">FileWriter</tspan>
        </text>
    </g>
    <g ed:width="176.297" ed:height="20.5" ed:layout="rightmap" id="262" transform="matrix(1,0,0,1,1787,3397)" ed:parentid="105">
        <path fill="#ffffff" d="M0,0L176.3,0L176.3,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L176.3,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="7" style="white-space:pre">装饰器模式VS简单的组合关系</tspan>
        </text>
    </g>
    <g ed:width="443.109" ed:height="20.5" ed:layout="rightmap" id="264" transform="matrix(1,0,0,1,1991,3155)" ed:parentid="262">
        <path fill="#ffffff" d="M0,0L443.1,0L443.1,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L443.1,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">1、装饰器类和原始类继承同样的父类，这样可以对原始类“嵌套”多个装饰器类。</tspan>
        </text>
    </g>
    <g ed:width="414.422" ed:height="64" ed:layout="rightmap" id="266" transform="matrix(1,0,0,1,2461,3134)" ed:parentid="264">
        <path fill="#ebebeb" d="M0,0L414.4,0L414.4,64L0,64L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st31">
            <tspan y="13" x="9" class="st32" style="white-space:pre">InputStream in = new </tspan>
            <tspan style="white-space:pre">FileInputStream</tspan>
            <tspan class="st32" style="white-space:pre">("/user/wangzheng/test.txt");</tspan>
            <tspan y="28" x="9" class="st32" style="white-space:pre">InputStream bin = new </tspan>
            <tspan style="white-space:pre">BufferedInputStream</tspan>
            <tspan class="st32" style="white-space:pre">(in); </tspan>
            <tspan y="43" x="9" class="st32" style="white-space:pre">DataInputStream din = new </tspan>
            <tspan style="white-space:pre">DataInputStream</tspan>
            <tspan class="st32" style="white-space:pre">(bin);</tspan>
            <tspan y="58" x="9" class="st32" style="white-space:pre">int data = din.readInt();</tspan>
        </text>
    </g>
    <g ed:width="385.578" ed:height="20.5" ed:layout="rightmap" id="268" transform="matrix(1,0,0,1,1991,3432)" ed:parentid="262">
        <path fill="#ffffff" d="M0,0L385.6,0L385.6,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L385.6,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="7" style="white-space:pre">2、装饰器类是对功能的增强，这是装饰器模式应用场景的重要特点。</tspan>
        </text>
    </g>
    <g ed:width="354" ed:height="20.5" ed:layout="rightmap" id="270" transform="matrix(1,0,0,1,2403,3319)" ed:parentid="268">
        <path fill="#ffffff" d="M0,0L354,0L354,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L354,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">代理模式中，代理类附加的是跟原始类无关的功能，监控、鉴权</tspan>
        </text>
    </g>
    <g ed:width="342" ed:height="20.5" ed:layout="rightmap" id="272" transform="matrix(1,0,0,1,2403,3560)" ed:parentid="268">
        <path fill="#ffffff" d="M0,0L342,0L342,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L342,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">装饰器模式中，装饰器类附加的是跟原始类相关的增强功能。</tspan>
        </text>
    </g>
    <g ed:width="321.141" ed:height="250" ed:layout="rightmap" id="274" transform="matrix(1,0,0,1,2784,3204)" ed:parentid="270">
        <path fill="#ebebeb" d="M0,0L321.1,0L321.1,250L0,250L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="15" x="9" style="white-space:pre">// 代理模式的代码结构(下面的接口也可以替换成抽象类)</tspan>
            <tspan y="30" x="9" style="white-space:pre">public interface IA { void f(); }</tspan>
            <tspan y="60" x="9" style="white-space:pre">public class A impelements IA { </tspan>
            <tspan y="75" x="9" style="white-space:pre">    public void f() { //... }</tspan>
            <tspan y="90" x="9" style="white-space:pre">}</tspan>
            <tspan y="120" x="9" style="white-space:pre">public class AProxy impements IA { </tspan>
            <tspan y="135" x="9" style="white-space:pre">    private IA a; </tspan>
            <tspan y="150" x="9" style="white-space:pre">    public AProxy(IA a) { this.a = a; }</tspan>
            <tspan y="165" x="9" style="white-space:pre">    public void f() { </tspan>
            <tspan y="182" x="9" style="white-space:pre">        // 新添加的代理逻辑</tspan>
            <tspan y="197" x="9" style="white-space:pre">        a.f();</tspan>
            <tspan y="214" x="9" style="white-space:pre">         // 新添加的代理逻辑</tspan>
            <tspan y="229" x="9" style="white-space:pre">    } </tspan>
            <tspan y="244" x="9" style="white-space:pre">}</tspan>
        </text>
    </g>
    <g ed:width="337.438" ed:height="220" ed:layout="rightmap" id="276" transform="matrix(1,0,0,1,2772,3461)" ed:parentid="272">
        <path fill="#ebebeb" d="M0,0L337.4,0L337.4,220L0,220L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="15" x="9" style="white-space:pre">// 装饰器模式的代码结构(下面的接口也可以替换成抽象类) </tspan>
            <tspan y="30" x="9" style="white-space:pre">public interface IA { void f(); }</tspan>
            <tspan y="60" x="9" style="white-space:pre">public class A impelements IA { public void f() { //... } }</tspan>
            <tspan y="90" x="9" style="white-space:pre">public class ADecorator impements IA { </tspan>
            <tspan y="105" x="9" style="white-space:pre">    private IA a; </tspan>
            <tspan y="120" x="9" style="white-space:pre">    public ADecorator(IA a) { this.a = a; }</tspan>
            <tspan y="135" x="9" style="white-space:pre">    public void f() { </tspan>
            <tspan y="152" x="9" style="white-space:pre">        // 功能增强代码</tspan>
            <tspan y="167" x="9" style="white-space:pre">        a.f(); </tspan>
            <tspan y="184" x="9" style="white-space:pre">        // 功能增强代码</tspan>
            <tspan y="199" x="9" style="white-space:pre">    } </tspan>
            <tspan y="214" x="9" style="white-space:pre">}</tspan>
        </text>
    </g>
    <g ed:width="615.6559999999999" ed:height="20.5" ed:layout="rightmap" id="278" transform="matrix(1,0,0,1,1787,3714)" ed:parentid="106">
        <path fill="#ffffff" d="M0,0L615.7,0L615.7,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L615.7,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="7" style="white-space:pre">它将不兼容的接口转换为可兼容的接口，让原本由于接口不兼容而不能一起工作的类可以一起工作（USB转接头）</tspan>
        </text>
    </g>
    <g ed:width="66" ed:height="20.5" ed:layout="rightmap" id="280" transform="matrix(1,0,0,1,1787,3908)" ed:parentid="106">
        <path fill="#ffffff" d="M0,0L66,0L66,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L66,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">类适配器</tspan>
        </text>
    </g>
    <g ed:width="78" ed:height="20.5" ed:layout="rightmap" id="282" transform="matrix(1,0,0,1,1787,4224)" ed:parentid="106">
        <path fill="#ffffff" d="M0,0L78,0L78,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L78,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">对象适配器</tspan>
        </text>
    </g>
    <g ed:width="126" ed:height="20.5" ed:layout="rightmap" id="284" transform="matrix(1,0,0,1,1880,3908)" ed:parentid="280">
        <path fill="#ffffff" d="M0,0L126,0L126,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L126,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">使用继承关系来实现</tspan>
        </text>
    </g>
    <g ed:width="126" ed:height="20.5" ed:layout="rightmap" id="286" transform="matrix(1,0,0,1,1892,4224)" ed:parentid="282">
        <path fill="#ffffff" d="M0,0L126,0L126,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L126,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">使用组合关系来实现</tspan>
        </text>
    </g>
    <g ed:width="454.688" ed:height="355" ed:layout="rightmap" id="288" transform="matrix(1,0,0,1,2033,3741)" ed:parentid="284">
        <path fill="#ebebeb" d="M0,0L454.7,0L454.7,355L0,355L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st31">
            <tspan y="13" x="9" class="st32" style="white-space:pre">public </tspan>
            <tspan class="st33" style="white-space:pre">interface</tspan>
            <tspan class="st32" style="white-space:pre"> </tspan>
            <tspan style="white-space:pre">ITarget</tspan>
            <tspan class="st32" style="white-space:pre"> { </tspan>
            <tspan y="28" x="9" class="st32" style="white-space:pre">    void f1(); </tspan>
            <tspan y="43" x="9" class="st32" style="white-space:pre">    void f2(); </tspan>
            <tspan y="58" x="9" class="st32" style="white-space:pre">    void fc(); </tspan>
            <tspan y="73" x="9" class="st32" style="white-space:pre">}</tspan>
            <tspan y="103" x="9" class="st32" style="white-space:pre">public class </tspan>
            <tspan style="white-space:pre">Adaptee</tspan>
            <tspan class="st32" style="white-space:pre"> { </tspan>
            <tspan y="118" x="9" class="st32" style="white-space:pre">    public void fa() { //... } </tspan>
            <tspan y="133" x="9" class="st32" style="white-space:pre">    public void fb() { //... } </tspan>
            <tspan y="148" x="9" class="st32" style="white-space:pre">    public void fc() { //... }</tspan>
            <tspan y="163" x="9" class="st32" style="white-space:pre"> }</tspan>
            <tspan y="195" x="9" class="st32" style="white-space:pre">// 类适配器: 基于继承</tspan>
            <tspan y="210" x="9" class="st32" style="white-space:pre">public class </tspan>
            <tspan style="white-space:pre">Adaptor</tspan>
            <tspan class="st32" style="white-space:pre"> </tspan>
            <tspan class="st33" style="white-space:pre">extends</tspan>
            <tspan class="st32" style="white-space:pre"> </tspan>
            <tspan style="white-space:pre">Adaptee</tspan>
            <tspan class="st32" style="white-space:pre"> </tspan>
            <tspan class="st33" style="white-space:pre">implements</tspan>
            <tspan class="st32" style="white-space:pre"> </tspan>
            <tspan style="white-space:pre">ITarget</tspan>
            <tspan class="st32" style="white-space:pre"> { </tspan>
            <tspan y="225" x="9" class="st32" style="white-space:pre">    public void f1() { </tspan>
            <tspan y="240" x="9" class="st32" style="white-space:pre">        super.fa();</tspan>
            <tspan y="255" x="9" class="st32" style="white-space:pre">    }</tspan>
            <tspan y="270" x="9" class="st32" style="white-space:pre">    public void f2() {</tspan>
            <tspan y="287" x="9" class="st32" style="white-space:pre">         //...重新实现f2()... </tspan>
            <tspan y="302" x="9" class="st32" style="white-space:pre">    }</tspan>
            <tspan y="334" x="9" class="st32" style="white-space:pre">    // 这里fc()不需要实现，直接继承自Adaptee，这是跟对象适配器最大的不同点</tspan>
            <tspan y="349" x="9" class="st32" style="white-space:pre">}</tspan>
        </text>
    </g>
    <g ed:width="267.922" ed:height="265" ed:layout="rightmap" id="290" transform="matrix(1,0,0,1,2045,4102)" ed:parentid="286">
        <path fill="#ebebeb" d="M0,0L267.9,0L267.9,265L0,265L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st34">
            <tspan y="15" x="9" style="white-space:pre">// 对象适配器：基于组合</tspan>
            <tspan y="30" x="9" class="st32" style="white-space:pre">public class </tspan>
            <tspan class="st35" style="white-space:pre">Adaptor</tspan>
            <tspan class="st32" style="white-space:pre"> </tspan>
            <tspan style="white-space:pre">implements</tspan>
            <tspan class="st32" style="white-space:pre"> </tspan>
            <tspan class="st35" style="white-space:pre">ITarget</tspan>
            <tspan class="st32" style="white-space:pre"> { </tspan>
            <tspan y="45" x="9" class="st32" style="white-space:pre">    private </tspan>
            <tspan class="st35" style="white-space:pre">Adaptee</tspan>
            <tspan class="st32" style="white-space:pre"> adaptee; </tspan>
            <tspan y="60" x="9" class="st32" style="white-space:pre">    public Adaptor(Adaptee adaptee) { </tspan>
            <tspan y="75" x="9" class="st32" style="white-space:pre">        this.adaptee = adaptee; </tspan>
            <tspan y="90" x="9" class="st32" style="white-space:pre">    }</tspan>
            <tspan y="105" x="9" class="st32" style="white-space:pre">    public void f1() { </tspan>
            <tspan y="120" x="9" class="st32" style="white-space:pre">        adaptee.fa(); </tspan>
            <tspan y="137" x="9" class="st32" style="white-space:pre">        //委托给Adaptee </tspan>
            <tspan y="152" x="9" class="st32" style="white-space:pre">    }</tspan>
            <tspan y="167" x="9" class="st32" style="white-space:pre">    public void f2() { </tspan>
            <tspan y="184" x="9" class="st32" style="white-space:pre">        //...重新实现f2()... </tspan>
            <tspan y="199" x="9" class="st32" style="white-space:pre">    }</tspan>
            <tspan y="214" x="9" class="st32" style="white-space:pre">    public void fc() { </tspan>
            <tspan y="229" x="9" class="st32" style="white-space:pre">        adaptee.fc(); </tspan>
            <tspan y="244" x="9" class="st32" style="white-space:pre">    } </tspan>
            <tspan y="259" x="9" class="st32" style="white-space:pre">}</tspan>
        </text>
    </g>
    <g ed:width="223.688" ed:height="20.5" ed:layout="rightmap" id="292" transform="matrix(1,0,0,1,1787,4423)" ed:parentid="106">
        <path fill="#ffffff" d="M0,0L223.7,0L223.7,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L223.7,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">类适配器 VS 对象适配器 选择哪一种？</tspan>
        </text>
    </g>
    <g ed:width="405.594" ed:height="20.5" ed:layout="rightmap" id="294" transform="matrix(1,0,0,1,2038,4374)" ed:parentid="292">
        <path fill="#ffffff" d="M0,0L405.6,0L405.6,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L405.6,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">一个是 Adaptee 接口的个数，另一个是 Adaptee 和 ITarget 的契合程度</tspan>
        </text>
    </g>
    <g ed:width="289.406" ed:height="20.5" ed:layout="rightmap" id="296" transform="matrix(1,0,0,1,2038,4401)" ed:parentid="292">
        <path fill="#ffffff" d="M0,0L289.4,0L289.4,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L289.4,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="7" style="white-space:pre">如果 Adaptee 接口并不多，两种实现方式都可以。</tspan>
        </text>
    </g>
    <g ed:width="145.406" ed:height="20.5" ed:layout="rightmap" id="298" transform="matrix(1,0,0,1,2038,4450)" ed:parentid="292">
        <path fill="#ffffff" d="M0,0L145.4,0L145.4,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L145.4,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="7" style="white-space:pre">如果 Adaptee 接口很多</tspan>
        </text>
    </g>
    <g ed:width="358.391" ed:height="20.5" ed:layout="rightmap" id="302" transform="matrix(1,0,0,1,2210,4436)" ed:parentid="298">
        <path fill="#ffffff" d="M0,0L358.4,0L358.4,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L358.4,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="7" style="white-space:pre">Adaptee 和 ITarget 接口定义大部分都相同，推荐使用类适配器</tspan>
        </text>
    </g>
    <g ed:width="382.391" ed:height="20.5" ed:layout="rightmap" id="304" transform="matrix(1,0,0,1,2210,4472)" ed:parentid="298">
        <path fill="#ffffff" d="M0,0L382.4,0L382.4,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L382.4,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="7" style="white-space:pre">Adaptee 和 ITarget 接口定义大部分都不相同，推荐使用对象适配器</tspan>
        </text>
    </g>
    <g ed:width="351.938" ed:height="37.5" ed:layout="rightmap" id="306" transform="matrix(1,0,0,1,2596,4428)" ed:parentid="302">
        <path fill="#ffffff" d="M0,0L351.9,0L351.9,37.5L0,37.5L0,0z"/>
        <path fill="none" d="M0,37.5L351.9,37.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.6" x="8" style="white-space:pre">Adaptor 复用父类 Adaptee 的接口，比起对象适配器的实现方</tspan>
            <tspan y="31.6" x="8" style="white-space:pre">式，Adaptor 的代码量要少一些。</tspan>
        </text>
    </g>
    <g ed:width="198" ed:height="20.5" ed:layout="rightmap" id="308" transform="matrix(1,0,0,1,2620,4472)" ed:parentid="304">
        <path fill="#ffffff" d="M0,0L198,0L198,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L198,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">因为组合结构相对于继承更加灵活</tspan>
        </text>
    </g>
    <g ed:width="150" ed:height="37.5" ed:layout="rightmap" id="310" transform="matrix(1,0,0,1,1787,4631)" ed:parentid="106">
        <path fill="#ffffff" d="M0,0L150,0L150,37.5L0,37.5L0,0z"/>
        <path fill="none" d="M0,37.5L150,37.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.6" x="8" style="white-space:pre">适配器模式应用场景总结</tspan>
            <tspan y="31.6" x="8" style="white-space:pre">（接口不兼容）</tspan>
        </text>
    </g>
    <g ed:width="493.063" ed:height="20.5" ed:layout="rightmap" id="312" transform="matrix(1,0,0,1,1964,4499)" ed:parentid="310">
        <path fill="#ffffff" d="M0,0L493.1,0L493.1,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L493.1,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="7" style="white-space:pre">适配器模式看作是一种“补偿模式”，用来补救设计上的缺陷。应用这种模式算是“无奈之举”</tspan>
        </text>
    </g>
    <g ed:width="153.172" ed:height="20.5" ed:layout="rightmap" id="314" transform="matrix(1,0,0,1,1964,4534)" ed:parentid="310">
        <path fill="#ffffff" d="M0,0L153.2,0L153.2,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L153.2,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="7" style="white-space:pre">1. 封装有缺陷的接口设计</tspan>
        </text>
    </g>
    <g ed:width="514" ed:height="37.5" ed:layout="rightmap" id="316" transform="matrix(1,0,0,1,2144,4526)" ed:parentid="314">
        <path fill="#ffffff" d="M0,0L514,0L514,37.5L0,37.5L0,0z"/>
        <path fill="none" d="M0,37.5L514,37.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.6" x="8" style="white-space:pre">依赖的外部系统在接口设计方面有缺陷，为了隔离设计上的缺陷，对外部系统提供的接口进行</tspan>
            <tspan y="31.6" x="8" style="white-space:pre">二次封装，抽象出更好的接口设计。</tspan>
        </text>
    </g>
    <g ed:width="153.172" ed:height="20.5" ed:layout="rightmap" id="318" transform="matrix(1,0,0,1,1964,4609)" ed:parentid="310">
        <path fill="#ffffff" d="M0,0L153.2,0L153.2,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L153.2,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="7" style="white-space:pre">2. 统一多个类的接口设计</tspan>
        </text>
    </g>
    <g ed:width="514" ed:height="37.5" ed:layout="rightmap" id="320" transform="matrix(1,0,0,1,2144,4570)" ed:parentid="318">
        <path fill="#ffffff" d="M0,0L514,0L514,37.5L0,37.5L0,0z"/>
        <path fill="none" d="M0,37.5L514,37.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.6" x="8" style="white-space:pre">某个功能的实现依赖多个外部系统（类），通过适配器模式，将它们的接口适配为统一的接口</tspan>
            <tspan y="31.6" x="8" style="white-space:pre">定义，然后使用多态的特性来复用代码逻辑</tspan>
        </text>
    </g>
    <g ed:width="578.3440000000001" ed:height="54.5" ed:layout="rightmap" id="324" transform="matrix(1,0,0,1,2144,4614)" ed:parentid="318">
        <path fill="#ffffff" d="M0,0L578.3,0L578.3,54.5L0,54.5L0,0z"/>
        <path fill="none" d="M0,54.5L578.3,54.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.6" x="8" style="white-space:pre">系统要对用户输入的文本内容做敏感词过滤，引入了多款第三方敏感词过滤系统，依次对用户输入的内容</tspan>
            <tspan y="31.6" x="8" style="white-space:pre">进行过滤。但是，每个系统提供的过滤接口都是不同的。</tspan>
            <tspan y="48.6" x="8" style="white-space:pre">使用适配器模式，将所有系统的接口适配为统一的接口定义，这样我们可以复用调用敏感词过滤的代码</tspan>
        </text>
    </g>
    <g ed:width="141.172" ed:height="20.5" ed:layout="rightmap" id="326" transform="matrix(1,0,0,1,1964,4675)" ed:parentid="310">
        <path fill="#ffffff" d="M0,0L141.2,0L141.2,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L141.2,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="7" style="white-space:pre">3. 替换依赖的外部系统</tspan>
        </text>
    </g>
    <g ed:width="570" ed:height="20.5" ed:layout="rightmap" id="328" transform="matrix(1,0,0,1,2132,4675)" ed:parentid="326">
        <path fill="#ffffff" d="M0,0L570,0L570,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L570,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">当把项目中依赖的一个外部系统替换为另一个外部系统的时候，利用适配器模式，可以减少对代码的改动</tspan>
        </text>
    </g>
    <g ed:width="117.172" ed:height="20.5" ed:layout="rightmap" id="330" transform="matrix(1,0,0,1,1964,4702)" ed:parentid="310">
        <path fill="#ffffff" d="M0,0L117.2,0L117.2,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L117.2,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="7" style="white-space:pre">4. 兼容老版本接口</tspan>
        </text>
    </g>
    <g ed:width="734.609" ed:height="20.5" ed:layout="rightmap" id="332" transform="matrix(1,0,0,1,2108,4702)" ed:parentid="330">
        <path fill="#ffffff" d="M0,0L734.6,0L734.6,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L734.6,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">在版本升级时，对于一些要废弃的接口，不直接将其删除，而是暂时保留，标注为 deprecated，并将内部实现逻辑委托为新的接口实现</tspan>
        </text>
    </g>
    <g ed:width="141.172" ed:height="20.5" ed:layout="rightmap" id="334" transform="matrix(1,0,0,1,1964,4755)" ed:parentid="310">
        <path fill="#ffffff" d="M0,0L141.2,0L141.2,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L141.2,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="7" style="white-space:pre">5. 适配不同格式的数据</tspan>
        </text>
    </g>
    <g ed:width="216.766" ed:height="20.5" ed:layout="rightmap" id="336" transform="matrix(1,0,0,1,1787,4838)" ed:parentid="106">
        <path fill="#ffffff" d="M0,0L216.8,0L216.8,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L216.8,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">剖析适配器模式在 Java 日志中的应用</tspan>
        </text>
    </g>
    <g ed:width="486" ed:height="20.5" ed:layout="rightmap" id="338" transform="matrix(1,0,0,1,2132,4729)" ed:parentid="334">
        <path fill="#ffffff" d="M0,0L486,0L486,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L486,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">把从不同征信系统拉取的不同格式的征信数据，统一为相同的格式，以方便存储和使用。</tspan>
        </text>
    </g>
    <g ed:width="518.4059999999999" ed:height="20.5" ed:layout="rightmap" id="340" transform="matrix(1,0,0,1,2132,4756)" ed:parentid="334">
        <path fill="#ffffff" d="M0,0L518.4,0L518.4,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L518.4,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="7" style="white-space:pre">Java 中的 Arrays.asList() 也可以看作一种数据适配器，将数组类型的数据转化为集合容器类型</tspan>
        </text>
    </g>
    <g ed:width="369.688" ed:height="18.5" ed:layout="rightmap" id="342" transform="matrix(1,0,0,1,2132,4783)" ed:parentid="334">
        <path fill="#ffffff" d="M0,0L369.7,0L369.7,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L369.7,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="12.7" x="8" style="white-space:pre">List&lt;String> stooges = Arrays.asList("Larry", "Moe", "Curly");</tspan>
        </text>
    </g>
    <g ed:width="514" ed:height="37.5" ed:layout="rightmap" id="344" transform="matrix(1,0,0,1,2031,4808)" ed:parentid="336">
        <path fill="#ffffff" d="M0,0L514,0L514,37.5L0,37.5L0,0z"/>
        <path fill="none" d="M0,37.5L514,37.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.6" x="8" style="white-space:pre">Slf4j 日志框架相当于 JDBC 规范，提供了一套打印日志的统一接口规范。不过，它只定义了接</tspan>
            <tspan y="31.6" x="8" style="white-space:pre">口，并没有提供具体的实现，需要配合其他日志框架（log4j、logback……）来使用。</tspan>
        </text>
    </g>
    <g ed:width="514" ed:height="37.5" ed:layout="rightmap" id="346" transform="matrix(1,0,0,1,2031,4852)" ed:parentid="336">
        <path fill="#ffffff" d="M0,0L514,0L514,37.5L0,37.5L0,0z"/>
        <path fill="none" d="M0,37.5L514,37.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.6" x="8" style="white-space:pre">Slf4j 不仅仅提供了统一的接口定义，还提供了针对不同日志框架的适配器。对不同日志框架的</tspan>
            <tspan y="31.6" x="8" style="white-space:pre">接口进行二次封装，适配成统一的 Slf4j 接口定义</tspan>
        </text>
    </g>
    <g ed:width="285.172" ed:height="20.5" ed:layout="rightmap" id="348" transform="matrix(1,0,0,1,1787,4950)" ed:parentid="106">
        <path fill="#ffffff" d="M0,0L285.2,0L285.2,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L285.2,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">代理、桥接、装饰器、适配器 4 种设计模式的区别</tspan>
        </text>
    </g>
    <g ed:width="393.172" ed:height="20.5" ed:layout="rightmap" id="350" transform="matrix(1,0,0,1,2099,4896)" ed:parentid="348">
        <path fill="#ffffff" d="M0,0L393.2,0L393.2,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L393.2,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">尽管代码结构相似，但这 4 种设计模式要解决的问题、应用场景不同，</tspan>
        </text>
    </g>
    <g ed:width="822" ed:height="20.5" ed:layout="rightmap" id="352" transform="matrix(1,0,0,1,2099,4923)" ed:parentid="348">
        <path fill="#ffffff" d="M0,0L822,0L822,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L822,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st31">
            <tspan y="14.7" x="8" style="white-space:pre">代理模式</tspan>
            <tspan class="st32" style="white-space:pre">：代理模式在不改变原始类接口的条件下，为原始类定义一个代理类，主要目的是</tspan>
            <tspan style="white-space:pre">控制访问</tspan>
            <tspan class="st32" style="white-space:pre">，而非加强功能，这是它跟装饰器模式最大的不同。</tspan>
        </text>
    </g>
    <g ed:width="606" ed:height="20.5" ed:layout="rightmap" id="354" transform="matrix(1,0,0,1,2099,4950)" ed:parentid="348">
        <path fill="#ffffff" d="M0,0L606,0L606,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L606,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st31">
            <tspan y="14.7" x="8" style="white-space:pre">桥接模式</tspan>
            <tspan class="st32" style="white-space:pre">：桥接模式的目的是将</tspan>
            <tspan style="white-space:pre">接口部分和实现部分分离</tspan>
            <tspan class="st32" style="white-space:pre">，从而让它们可以较为容易、也相对独立地加以改变。</tspan>
        </text>
    </g>
    <g ed:width="630" ed:height="20.5" ed:layout="rightmap" id="356" transform="matrix(1,0,0,1,2099,4977)" ed:parentid="348">
        <path fill="#ffffff" d="M0,0L630,0L630,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L630,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st31">
            <tspan y="14.7" x="8" style="white-space:pre">装饰器模式</tspan>
            <tspan class="st32" style="white-space:pre">：装饰者模式在不改变原始类接口的情况下，对</tspan>
            <tspan style="white-space:pre">原始类功能进行增强</tspan>
            <tspan class="st32" style="white-space:pre">，并且支持</tspan>
            <tspan style="white-space:pre">多个装饰器的嵌套使用。</tspan>
        </text>
    </g>
    <g ed:width="762" ed:height="20.5" ed:layout="rightmap" id="358" transform="matrix(1,0,0,1,2099,5004)" ed:parentid="348">
        <path fill="#ffffff" d="M0,0L762,0L762,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L762,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st31">
            <tspan y="14.7" x="8" style="white-space:pre">适配器模式</tspan>
            <tspan class="st32" style="white-space:pre">：适配器模式是一种</tspan>
            <tspan style="white-space:pre">事后的补救策略</tspan>
            <tspan class="st32" style="white-space:pre">。适配器提供</tspan>
            <tspan style="white-space:pre">跟原始类不同的接口</tspan>
            <tspan class="st32" style="white-space:pre">，而代理模式、装饰器模式提供的都是跟原始类相同的接口</tspan>
        </text>
    </g>
    <g ed:width="222" ed:height="20.5" ed:layout="leftmap" id="360" transform="matrix(1,0,0,1,589,3207)" ed:parentid="362">
        <path fill="#ffffff" d="M0,0L222,0L222,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L222,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st31">
            <tspan y="14.7" x="8" class="st32" style="white-space:pre">将</tspan>
            <tspan style="white-space:pre">多个内部模块调用封装在一个类</tspan>
            <tspan class="st32" style="white-space:pre">中。</tspan>
        </text>
    </g>
    <g ed:width="138" ed:height="20.5" ed:layout="leftmap" id="362" transform="matrix(1,0,0,1,838,3234)" ed:parentid="107">
        <path fill="#ffffff" d="M0,0L138,0L138,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L138,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">门面模式的原理与实现</tspan>
        </text>
    </g>
    <g ed:width="150" ed:height="20.5" ed:layout="leftmap" id="364" transform="matrix(1,0,0,1,826,3350)" ed:parentid="107">
        <path fill="#ffffff" d="M0,0L150,0L150,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L150,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">门面模式的应用场景举例</tspan>
        </text>
    </g>
    <g ed:width="352.734" ed:height="20.5" ed:layout="leftmap" id="366" transform="matrix(1,0,0,1,458,3234)" ed:parentid="362">
        <path fill="#ffffff" d="M0,0L352.7,0L352.7,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L352.7,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="7" style="white-space:pre">子系统B有一个功能，需要同时依赖子系统A的3个模块来实现。</tspan>
        </text>
    </g>
    <g ed:width="423.516" ed:height="20.5" ed:layout="leftmap" id="368" transform="matrix(1,0,0,1,387,3261)" ed:parentid="362">
        <path fill="#ffffff" d="M0,0L423.5,0L423.5,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L423.5,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">APP响应速度比较慢，排查之后发现，是因为过多的接口调用过多的网络通信</tspan>
        </text>
    </g>
    <g ed:width="117.172" ed:height="20.5" ed:layout="leftmap" id="370" transform="matrix(1,0,0,1,682,3288)" ed:parentid="364">
        <path fill="#ffffff" d="M0,0L117.2,0L117.2,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L117.2,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="7" style="white-space:pre">1. 解决易用性问题</tspan>
        </text>
    </g>
    <g ed:width="486" ed:height="20.5" ed:layout="leftmap" id="372" transform="matrix(1,0,0,1,169,3288)" ed:parentid="370">
        <path fill="#ffffff" d="M0,0L486,0L486,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L486,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">用来封装系统的底层实现，隐藏系统的复杂性，提供一组更加简单易用、更高层的接口。</tspan>
        </text>
    </g>
    <g ed:width="105.172" ed:height="20.5" ed:layout="leftmap" id="374" transform="matrix(1,0,0,1,694,3315)" ed:parentid="364">
        <path fill="#ffffff" d="M0,0L105.2,0L105.2,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L105.2,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="7" style="white-space:pre">2. 解决性能问题</tspan>
        </text>
    </g>
    <g ed:width="540.953" ed:height="20.5" ed:layout="leftmap" id="376" transform="matrix(1,0,0,1,126,3315)" ed:parentid="374">
        <path fill="#ffffff" d="M0,0L541,0L541,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L541,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">通过将多个接口调用替换为一个门面接口调用，减少网络通信成本，提高 App 客户端的响应速度。</tspan>
        </text>
    </g>
    <g ed:width="141.172" ed:height="20.5" ed:layout="leftmap" id="378" transform="matrix(1,0,0,1,658,3377)" ed:parentid="364">
        <path fill="#ffffff" d="M0,0L141.2,0L141.2,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L141.2,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="7" style="white-space:pre">3. 解决分布式事务问题</tspan>
        </text>
    </g>
    <g ed:width="426" ed:height="20.5" ed:layout="leftmap" id="380" transform="matrix(1,0,0,1,205,3342)" ed:parentid="378">
        <path fill="#ffffff" d="M0,0L426,0L426,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L426,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st31">
            <tspan y="14.7" x="8" class="st32" style="white-space:pre">通过引入</tspan>
            <tspan style="white-space:pre">分布式事务框架</tspan>
            <tspan class="st32" style="white-space:pre">或者</tspan>
            <tspan style="white-space:pre">事后补偿</tspan>
            <tspan class="st32" style="white-space:pre">的机制来解决，但代码实现都比较复杂</tspan>
        </text>
    </g>
    <g ed:width="374.875" ed:height="20.5" ed:layout="leftmap" id="382" transform="matrix(1,0,0,1,256,3369)" ed:parentid="378">
        <path fill="#ffffff" d="M0,0L374.9,0L374.9,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L374.9,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st31">
            <tspan y="14.7" x="8" class="st32" style="white-space:pre">最简单的解决方案是，利用</tspan>
            <tspan style="white-space:pre">数据库事务</tspan>
            <tspan class="st32" style="white-space:pre">或者 </tspan>
            <tspan style="white-space:pre">Spring 框架</tspan>
            <tspan class="st32" style="white-space:pre">提供的事务</tspan>
        </text>
    </g>
    <g ed:width="530.172" ed:height="37.5" ed:layout="leftmap" id="384" transform="matrix(1,0,0,1,100,3396)" ed:parentid="378">
        <path fill="#ffffff" d="M0,0L530.2,0L530.2,37.5L0,37.5L0,0z"/>
        <path fill="none" d="M0,37.5L530.2,37.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.6" x="8" style="white-space:pre">在一个事务中，要求创建用户和创建钱包这两个 SQL 操作要在一个接口中完成。借鉴门面模式的</tspan>
            <tspan y="31.6" x="8" style="white-space:pre">思想，再设计一个包裹这两个操作的新接口，让新接口在一个事务中执行两个 SQL 操作。</tspan>
        </text>
    </g>
    <g ed:width="85" ed:height="22.5" ed:layout="leftmap" id="386" transform="matrix(1,0,0,1,891,3466)" ed:parentid="107">
        <path fill="#ffffff" d="M0,0L85,0L85,22.5L0,22.5L0,0z"/>
        <path fill="none" d="M0,22.5L85,22.5" stroke="#696969" stroke-linejoin="round"/>
        <g transform="translate(7,2.25)">
            <use xlink:href="#flag1" transform="translate(0,0)"/>
        </g>
        <text class="st30">
            <tspan y="15.7" x="27" style="white-space:pre">总结回归</tspan>
        </text>
    </g>
    <symbol id="flag1">
        <image xlink:href="" width="16" height="16"/>
    </symbol>
    <g ed:width="351.531" ed:height="20.5" ed:layout="leftmap" id="389" transform="matrix(1,0,0,1,512,3440)" ed:parentid="386">
        <path fill="#ffffff" d="M0,0L351.5,0L351.5,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L351.5,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">类、模块、系统之间的“通信”，一般都是通过接口调用来完成的</tspan>
        </text>
    </g>
    <g ed:width="522" ed:height="20.5" ed:layout="leftmap" id="391" transform="matrix(1,0,0,1,342,3467)" ed:parentid="386">
        <path fill="#ffffff" d="M0,0L522,0L522,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L522,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">完成接口设计，就相当于完成了一半的开发任务。只要接口设计得好，那代码就差不到哪里去。</tspan>
        </text>
    </g>
    <g ed:width="510" ed:height="20.5" ed:layout="leftmap" id="393" transform="matrix(1,0,0,1,354,3494)" ed:parentid="386">
        <path fill="#ffffff" d="M0,0L510,0L510,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L510,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">尽量保持接口的可复用性，但针对特殊情况，允许提供冗余的门面接口，来提供更易用的接口</tspan>
        </text>
    </g>
    <g ed:width="234" ed:height="20.5" ed:layout="leftmap" id="395" transform="matrix(1,0,0,1,573,2455)" ed:parentid="399">
        <path fill="#ffffff" d="M0,0L234,0L234,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L234,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st31">
            <tspan y="14.7" x="8" class="st32" style="white-space:pre">主要是用来处理</tspan>
            <tspan style="white-space:pre">树形结构数据</tspan>
            <tspan class="st32" style="white-space:pre">（部门树）</tspan>
        </text>
    </g>
    <g ed:width="174" ed:height="20.5" ed:layout="leftmap" id="397" transform="matrix(1,0,0,1,633,2482)" ed:parentid="399">
        <path fill="#ffffff" d="M0,0L174,0L174,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L174,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">对层级数据递归调用执行操作</tspan>
        </text>
    </g>
    <g ed:width="138" ed:height="20.5" ed:layout="leftmap" id="399" transform="matrix(1,0,0,1,834,2496)" ed:parentid="108">
        <path fill="#ffffff" d="M0,0L138,0L138,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L138,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">组合模式的原理与实现</tspan>
        </text>
    </g>
    <g ed:width="604.125" ed:height="20.5" ed:layout="leftmap" id="401" transform="matrix(1,0,0,1,203,2509)" ed:parentid="399">
        <path fill="#ffffff" d="M0,0L604.1,0L604.1,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L604.1,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">将一组对象（文件和目录）组织成树形结构，以表示一种‘部分 - 整体’的层次结构（目录与子目录的嵌套结构）</tspan>
        </text>
    </g>
    <g ed:width="498" ed:height="20.5" ed:layout="leftmap" id="403" transform="matrix(1,0,0,1,309,2536)" ed:parentid="399">
        <path fill="#ffffff" d="M0,0L498,0L498,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L498,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">组合模式让客户端可以统一单个对象（文件）和组合对象（目录）的处理逻辑（递归遍历）</tspan>
        </text>
    </g>
    <g ed:width="150" ed:height="20.5" ed:layout="leftmap" id="405" transform="matrix(1,0,0,1,822,2858)" ed:parentid="108">
        <path fill="#ffffff" d="M0,0L150,0L150,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L150,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">组合模式的应用场景举例</tspan>
        </text>
    </g>
    <g ed:width="66" ed:height="20.5" ed:layout="leftmap" id="407" transform="matrix(1,0,0,1,729,2563)" ed:parentid="405">
        <path fill="#ffffff" d="M0,0L66,0L66,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L66,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">级联删除</tspan>
        </text>
    </g>
    <g ed:width="512.391" ed:height="291" ed:layout="leftmap" id="418" transform="matrix(1,0,0,1,282,2590)" ed:parentid="405">
        <path fill="#ebebeb" d="M0,0L512.4,0L512.4,291L0,291L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st31">
            <tspan y="13" x="9" class="st32" style="white-space:pre">public static class Department{</tspan>
            <tspan y="28" x="9" class="st32" style="white-space:pre">        private String name;</tspan>
            <tspan y="43" x="9" class="st32" style="white-space:pre">        private List&lt;Department> children = new ArrayList&lt;Department>();</tspan>
            <tspan y="73" x="9" class="st32" style="white-space:pre">        public Department(String name) {this.name = name;}</tspan>
            <tspan y="88" x="9" class="st32" style="white-space:pre">        public String getName() {return name; }</tspan>
            <tspan y="103" x="9" class="st32" style="white-space:pre">        public void setName(String name) {this.name = name;}</tspan>
            <tspan y="118" x="9" class="st32" style="white-space:pre">        public List&lt;Department> getChildren() {return children;}</tspan>
            <tspan y="133" x="9" class="st32" style="white-space:pre">        public void setChildren(List&lt;Department> children) {this.children = children;  }</tspan>
            <tspan y="163" x="9" class="st32" style="white-space:pre">        public void </tspan>
            <tspan style="white-space:pre">remove</tspan>
            <tspan class="st32" style="white-space:pre">(){</tspan>
            <tspan y="178" x="9" class="st32" style="white-space:pre">            if(children.size()>0){</tspan>
            <tspan y="193" x="9" class="st32" style="white-space:pre">                for(Department child : children){</tspan>
            <tspan y="208" x="9" class="st32" style="white-space:pre">                    child.remove();</tspan>
            <tspan y="223" x="9" class="st32" style="white-space:pre">                }</tspan>
            <tspan y="238" x="9" class="st32" style="white-space:pre">            }</tspan>
            <tspan y="255" x="9" class="st32" style="white-space:pre">            System.out.println("删除部门 【" + name + "】");</tspan>
            <tspan y="270" x="9" class="st32" style="white-space:pre">        }</tspan>
            <tspan y="285" x="9" class="st32" style="white-space:pre">    }</tspan>
        </text>
    </g>
    <g ed:width="370" ed:height="286" ed:layout="leftmap" id="420" transform="matrix(1,0,0,1,425,2888)" ed:parentid="405">
        <path fill="#ebebeb" d="M0,0L370,0L370,286L0,286L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st31">
            <tspan y="13" x="9" class="st32" style="white-space:pre">public static void main(String[] args) {</tspan>
            <tspan y="30" x="9" class="st32" style="white-space:pre">        Department leafDept1 = new Department("叶子部门1");</tspan>
            <tspan y="47" x="9" class="st32" style="white-space:pre">        Department leafDept2 = new Department("叶子部门2");</tspan>
            <tspan y="64" x="9" class="st32" style="white-space:pre">        Department leafDept3 = new Department("叶子部门3");</tspan>
            <tspan y="96" x="9" class="st32" style="white-space:pre">        Department subDept1 = new Department("子部门1");</tspan>
            <tspan y="111" x="9" class="st32" style="white-space:pre">        subDept1.getChildren().add(leafDept1);</tspan>
            <tspan y="126" x="9" class="st32" style="white-space:pre">        subDept1.getChildren().add(leafDept2);</tspan>
            <tspan y="158" x="9" class="st32" style="white-space:pre">        Department subDept2 = new Department("子部门2");</tspan>
            <tspan y="173" x="9" class="st32" style="white-space:pre">        subDept2.getChildren().add(leafDept3);</tspan>
            <tspan y="205" x="9" class="st32" style="white-space:pre">        Department parentDept = new Department("父部门");</tspan>
            <tspan y="220" x="9" class="st32" style="white-space:pre">        parentDept.getChildren().add(subDept1);</tspan>
            <tspan y="235" x="9" class="st32" style="white-space:pre">        parentDept.getChildren().add(subDept2);</tspan>
            <tspan y="265" x="9" class="st32" style="white-space:pre">        parentDept.</tspan>
            <tspan style="white-space:pre">remove</tspan>
            <tspan class="st32" style="white-space:pre">();</tspan>
            <tspan y="280" x="9" class="st32" style="white-space:pre">    }</tspan>
        </text>
    </g>
    <g ed:width="126" ed:height="20.5" ed:layout="leftmap" id="422" transform="matrix(1,0,0,1,846,1553)" ed:parentid="109">
        <path fill="#ffffff" d="M0,0L126,0L126,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L126,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">享元模式原理与实现</tspan>
        </text>
    </g>
    <g ed:width="402" ed:height="37.5" ed:layout="leftmap" id="426" transform="matrix(1,0,0,1,417,1531)" ed:parentid="422">
        <path fill="#ffffff" d="M0,0L402,0L402,37.5L0,37.5L0,0z"/>
        <path fill="none" d="M0,37.5L402,37.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st31">
            <tspan y="14.6" x="8" class="st32" style="white-space:pre">“享元”：被</tspan>
            <tspan style="white-space:pre">共享的单元</tspan>
            <tspan class="st32" style="white-space:pre">。</tspan>
            <tspan y="31.6" x="8" class="st32" style="white-space:pre">享元模式的意图是复用对象，节省内存，前提是享元对象是不可变对象。</tspan>
        </text>
    </g>
    <g ed:width="518.0940000000001" ed:height="20.5" ed:layout="leftmap" id="428" transform="matrix(1,0,0,1,301,1575)" ed:parentid="422">
        <path fill="#ffffff" d="M0,0L518.1,0L518.1,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L518.1,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">通过工厂模式，在工厂类中，通过一个 Map 来缓存已经创建过的享元对象，来达到复用的目的</tspan>
        </text>
    </g>
    <g ed:width="109.906" ed:height="20.5" ed:layout="leftmap" id="430" transform="matrix(1,0,0,1,862,1642)" ed:parentid="109">
        <path fill="#ffffff" d="M0,0L109.9,0L109.9,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L109.9,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="7" style="white-space:pre">享元模式 vs 单例</tspan>
        </text>
    </g>
    <g ed:width="109.906" ed:height="20.5" ed:layout="leftmap" id="432" transform="matrix(1,0,0,1,862,1732)" ed:parentid="109">
        <path fill="#ffffff" d="M0,0L109.9,0L109.9,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L109.9,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="7" style="white-space:pre">享元模式 vs 缓存</tspan>
        </text>
    </g>
    <g ed:width="121.906" ed:height="20.5" ed:layout="leftmap" id="434" transform="matrix(1,0,0,1,850,1820)" ed:parentid="109">
        <path fill="#ffffff" d="M0,0L121.9,0L121.9,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L121.9,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="7" style="white-space:pre">享元模式 vs 对象池</tspan>
        </text>
    </g>
    <g ed:width="234" ed:height="20.5" ed:layout="leftmap" id="436" transform="matrix(1,0,0,1,601,1602)" ed:parentid="430">
        <path fill="#ffffff" d="M0,0L234,0L234,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L234,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">在单例模式中，一个类只能创建一个对象</tspan>
        </text>
    </g>
    <g ed:width="402" ed:height="20.5" ed:layout="leftmap" id="438" transform="matrix(1,0,0,1,433,1629)" ed:parentid="430">
        <path fill="#ffffff" d="M0,0L402,0L402,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L402,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">在享元模式中，一个类可以创建多个对象，每个对象被多处代码引用共享</tspan>
        </text>
    </g>
    <g ed:width="210" ed:height="20.5" ed:layout="leftmap" id="440" transform="matrix(1,0,0,1,625,1656)" ed:parentid="430">
        <path fill="#ffffff" d="M0,0L210,0L210,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L210,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">应用多例模式是为了限制对象的个数</tspan>
        </text>
    </g>
    <g ed:width="234" ed:height="20.5" ed:layout="leftmap" id="442" transform="matrix(1,0,0,1,601,1683)" ed:parentid="430">
        <path fill="#ffffff" d="M0,0L234,0L234,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L234,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">应用享元模式是为了对象复用，节省内存</tspan>
        </text>
    </g>
    <g ed:width="351.531" ed:height="37.5" ed:layout="leftmap" id="444" transform="matrix(1,0,0,1,483,1710)" ed:parentid="432">
        <path fill="#ffffff" d="M0,0L351.5,0L351.5,37.5L0,37.5L0,0z"/>
        <path fill="none" d="M0,37.5L351.5,37.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st31">
            <tspan y="14.6" x="8" class="st32" style="white-space:pre">在享元模式的实现中，通过工厂类来“缓存”已经创建好的对象。</tspan>
            <tspan y="31.6" x="8" class="st32" style="white-space:pre">“</tspan>
            <tspan style="white-space:pre">缓存</tspan>
            <tspan class="st32" style="white-space:pre">”实际上是“存储”的意思</tspan>
        </text>
    </g>
    <g ed:width="440.797" ed:height="20.5" ed:layout="leftmap" id="446" transform="matrix(1,0,0,1,394,1754)" ed:parentid="432">
        <path fill="#ffffff" d="M0,0L440.8,0L440.8,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L440.8,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st31">
            <tspan y="14.7" x="7" class="st32" style="white-space:pre">“数据库缓存”“CPU 缓存”“MemCache </tspan>
            <tspan style="white-space:pre">缓存</tspan>
            <tspan class="st32" style="white-space:pre">”主要是为了提高访问效率，而非复用</tspan>
        </text>
    </g>
    <g ed:width="514" ed:height="37.5" ed:layout="leftmap" id="448" transform="matrix(1,0,0,1,309,1781)" ed:parentid="434">
        <path fill="#ffffff" d="M0,0L514,0L514,37.5L0,37.5L0,0z"/>
        <path fill="none" d="M0,37.5L514,37.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st31">
            <tspan y="14.6" x="8" class="st32" style="white-space:pre">享元模式中的“</tspan>
            <tspan style="white-space:pre">复用</tspan>
            <tspan class="st32" style="white-space:pre">”可以理解为“共享使用”，在整个生命周期中，都是被所有使用者共享的，</tspan>
            <tspan y="31.6" x="8" class="st32" style="white-space:pre">主要目的是节省空间。</tspan>
        </text>
    </g>
    <g ed:width="514" ed:height="54.5" ed:layout="leftmap" id="450" transform="matrix(1,0,0,1,309,1825)" ed:parentid="434">
        <path fill="#ffffff" d="M0,0L514,0L514,54.5L0,54.5L0,0z"/>
        <path fill="none" d="M0,54.5L514,54.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st31">
            <tspan y="14.6" x="8" class="st32" style="white-space:pre">池化技术中的“</tspan>
            <tspan style="white-space:pre">复用</tspan>
            <tspan class="st32" style="white-space:pre">”可以理解为“重复使用”，主要目的是节省时间（比如从数据库池中取一个</tspan>
            <tspan y="31.6" x="8" class="st32" style="white-space:pre">连接，不需要重新创建）。在任意时刻，每一个对象、连接、线程，并不会被多处使用，而是</tspan>
            <tspan y="48.6" x="8" class="st32" style="white-space:pre">被一个使用者独占，当使用完成之后，放回到池中，再由其他使用者重复利用。</tspan>
        </text>
    </g>
    <g ed:width="201.656" ed:height="20.5" ed:layout="leftmap" id="452" transform="matrix(1,0,0,1,770,2044)" ed:parentid="109">
        <path fill="#ffffff" d="M0,0L201.7,0L201.7,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L201.7,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="7" style="white-space:pre">享元模式在 Java Integer 中的应用</tspan>
        </text>
    </g>
    <g ed:width="318" ed:height="37.5" ed:layout="leftmap" id="454" transform="matrix(1,0,0,1,425,1886)" ed:parentid="452">
        <path fill="#ffffff" d="M0,0L318,0L318,37.5L0,37.5L0,0z"/>
        <path fill="none" d="M0,37.5L318,37.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.6" x="8" style="white-space:pre">自动装箱，就是自动将基本数据类型转换为包装器类型。</tspan>
            <tspan y="31.6" x="8" style="white-space:pre">自动拆箱，就是自动将包装器类型转化为基本数据类型。</tspan>
        </text>
    </g>
    <g ed:width="366.875" ed:height="38" ed:layout="leftmap" id="456" transform="matrix(1,0,0,1,376,1930)" ed:parentid="452">
        <path fill="#ebebeb" d="M0,0L366.9,0L366.9,38L0,38L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="15" x="9" style="white-space:pre">Integer i = 59；底层执行了：Integer i = Integer.valueOf(59);</tspan>
            <tspan y="32" x="9" style="white-space:pre">int j = i;            底层执行了：int j = i.intValue();</tspan>
        </text>
    </g>
    <g ed:width="188.969" ed:height="20.5" ed:layout="leftmap" id="458" transform="matrix(1,0,0,1,554,2088)" ed:parentid="452">
        <path fill="#ffffff" d="M0,0L189,0L189,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L189,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">Java 对象在内存中是如何存储的</tspan>
        </text>
    </g>
    <g ed:width="301.234" ed:height="19" ed:layout="leftmap" id="460" transform="matrix(1,0,0,1,226,1974)" ed:parentid="458">
        <path fill="#ebebeb" d="M0,0L301.2,0L301.2,19L0,19L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="13" x="9" style="white-space:pre">User a = new User(123, 23); // id=123, age=23</tspan>
        </text>
    </g>
    <g ed:width="206.016" ed:height="20.5" ed:layout="leftmap" id="462" transform="matrix(1,0,0,1,321,2000)" ed:parentid="458">
        <path fill="#ffffff" d="M0,0L206,0L206,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L206,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="8" style="white-space:pre">a 存储的值是 User 对象的内存地址</tspan>
        </text>
    </g>
    <g ed:width="322.594" ed:height="37.5" ed:layout="leftmap" id="464" transform="matrix(1,0,0,1,205,2027)" ed:parentid="458">
        <path fill="#ffffff" d="M0,0L322.6,0L322.6,37.5L0,37.5L0,0z"/>
        <path fill="none" d="M0,37.5L322.6,37.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.6" x="8" style="white-space:pre">“==”实际上是在判断两个局部变量存储的地址是否相同。</tspan>
            <tspan y="31.6" x="8" style="white-space:pre">即在判断两个局部变量是否指向相同的对象。</tspan>
        </text>
    </g>
    <g ed:width="235.578" ed:height="64" ed:layout="leftmap" id="466" transform="matrix(1,0,0,1,292,2071)" ed:parentid="458">
        <path fill="#ebebeb" d="M0,0L235.6,0L235.6,64L0,64L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="13" x="9" style="white-space:pre">Integer i1 = 56;   Integer i2 = 56; </tspan>
            <tspan y="28" x="9" style="white-space:pre">Integer i3 = 129; Integer i4 = 129;  </tspan>
            <tspan y="43" x="9" style="white-space:pre">System.out.println(i1 == i2);  //true</tspan>
            <tspan y="58" x="9" style="white-space:pre">System.out.println(i3 == i4);  //false</tspan>
        </text>
    </g>
    <g ed:width="346.484" ed:height="20.5" ed:layout="leftmap" id="468" transform="matrix(1,0,0,1,181,2141)" ed:parentid="458">
        <path fill="#ffffff" d="M0,0L346.5,0L346.5,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L346.5,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st31">
            <tspan y="14.7" x="7" class="st32" style="white-space:pre"> Integer 用到了</tspan>
            <tspan style="white-space:pre">享元模式</tspan>
            <tspan class="st32" style="white-space:pre">来复用对象,导致了这样的运行结果。</tspan>
        </text>
    </g>
    <g ed:width="506.141" ed:height="54.5" ed:layout="leftmap" id="470" transform="matrix(1,0,0,1,21,2168)" ed:parentid="458">
        <path fill="#ffffff" d="M0,0L506.1,0L506.1,54.5L0,54.5L0,0z"/>
        <path fill="none" d="M0,54.5L506.1,54.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.6" x="7" style="white-space:pre">通过自动装箱，调用 valueOf() 来创建 Integer 对象时，</tspan>
            <tspan y="31.6" x="7" style="white-space:pre">如果要创建的 Integer 对象的值在 -128 到 127 之间，会从 IntegerCache 类中直接返回，</tspan>
            <tspan y="48.6" x="7" style="white-space:pre">否则才调用 new 方法创建。</tspan>
        </text>
    </g>
    <g ed:width="194.781" ed:height="20.5" ed:layout="leftmap" id="472" transform="matrix(1,0,0,1,777,2316)" ed:parentid="109">
        <path fill="#ffffff" d="M0,0L194.8,0L194.8,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L194.8,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="7" style="white-space:pre">享元模式在 Java String 中的应用</tspan>
        </text>
    </g>
    <g ed:width="263.719" ed:height="68" ed:layout="leftmap" id="474" transform="matrix(1,0,0,1,486,2229)" ed:parentid="472">
        <path fill="#ebebeb" d="M0,0L263.7,0L263.7,68L0,68L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="15" x="9" style="white-space:pre">String s1 = "小争哥"; String s2 = "小争哥"; </tspan>
            <tspan y="32" x="9" style="white-space:pre">String s3 = new String("小争哥"); </tspan>
            <tspan y="47" x="9" style="white-space:pre">System.out.println(s1 == s2); </tspan>
            <tspan y="62" x="9" style="white-space:pre">System.out.println(s1 == s3);</tspan>
        </text>
    </g>
    <g ed:width="272.016" ed:height="20.5" ed:layout="leftmap" id="476" transform="matrix(1,0,0,1,478,2304)" ed:parentid="472">
        <path fill="#ffffff" d="M0,0L272,0L272,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L272,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st31">
            <tspan y="14.7" x="8" class="st32" style="white-space:pre">String 类利用</tspan>
            <tspan style="white-space:pre">享元模式</tspan>
            <tspan class="st32" style="white-space:pre">来复用相同的字符串常量</tspan>
        </text>
    </g>
    <g ed:width="437.219" ed:height="20.5" ed:layout="leftmap" id="478" transform="matrix(1,0,0,1,313,2331)" ed:parentid="472">
        <path fill="#ffffff" d="M0,0L437.2,0L437.2,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L437.2,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st31">
            <tspan y="14.7" x="7" class="st32" style="white-space:pre">JVM 会专门开辟一块存储区来存储字符串常量，这块存储区叫作“</tspan>
            <tspan style="white-space:pre">字符串常量池</tspan>
            <tspan class="st32" style="white-space:pre">”</tspan>
        </text>
    </g>
    <g ed:width="398.891" ed:height="20.5" ed:layout="leftmap" id="480" transform="matrix(1,0,0,1,351,2358)" ed:parentid="472">
        <path fill="#ffffff" d="M0,0L398.9,0L398.9,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L398.9,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.7" x="7" style="white-space:pre">Integer 类中要共享的对象，是在类加载的时候，就集中一次性创建好的</tspan>
        </text>
    </g>
    <g ed:width="514" ed:height="37.5" ed:layout="leftmap" id="482" transform="matrix(1,0,0,1,236,2385)" ed:parentid="472">
        <path fill="#ffffff" d="M0,0L514,0L514,37.5L0,37.5L0,0z"/>
        <path fill="none" d="M0,37.5L514,37.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st30">
            <tspan y="14.6" x="8" style="white-space:pre">对于字符串来说，只能在某个字符串常量第一次被用到的时候，存储到常量池中，当之后再用</tspan>
            <tspan y="31.6" x="8" style="white-space:pre">到的时候，直接引用常量池中已经存在的即可</tspan>
        </text>
    </g>
    <symbol id="plus">
        <path fill="url(#lg3)" d="M11,6C11,8.8,8.8,11,6,11C3.2,11,1,8.8,1,6C1,3.2,3.2,1,6,1C8.8,1,11,3.2,11,6z"/>
        <path fill="none" d="M11,6C11,8.8,8.8,11,6,11C3.2,11,1,8.8,1,6C1,3.2,3.2,1,6,1C8.8,1,11,3.2,11,6zM3,6L9,6M6,3L6,9" stroke-width="0.7" stroke="#46a000"/>
    </symbol>
    <symbol id="minus">
        <path fill="url(#lg3)" d="M11,6C11,8.8,8.8,11,6,11C3.2,11,1,8.8,1,6C1,3.2,3.2,1,6,1C8.8,1,11,3.2,11,6z"/>
        <path fill="none" d="M11,6C11,8.8,8.8,11,6,11C3.2,11,1,8.8,1,6C1,3.2,3.2,1,6,1C8.8,1,11,3.2,11,6zM3,6L9,6" stroke-width="0.7" stroke="#46a000"/>
    </symbol>
    <g transform="translate(1560,2517)" ed:togtopicid="101">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1746,892)" ed:togtopicid="103">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1746,2210)" ed:togtopicid="104">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1761,3163)" ed:togtopicid="105">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1761,4363)" ed:togtopicid="106">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(990,3355)" ed:togtopicid="107">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(986,2809)" ed:togtopicid="108">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(986,1971)" ed:togtopicid="109">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1318,2104)" ed:togtopicid="125">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1963,321)" ed:togtopicid="128">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2128,157)" ed:togtopicid="130">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2260,418)" ed:togtopicid="132">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2007,762)" ed:togtopicid="134">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1935,1284)" ed:togtopicid="136">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2128,582)" ed:togtopicid="144">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2241,1006)" ed:togtopicid="156">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1899,1709)" ed:togtopicid="160">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2115,1674)" ed:togtopicid="162">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1982,1714)" ed:togtopicid="164">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2007,1750)" ed:togtopicid="170">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1847,1874)" ed:togtopicid="181">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2029,1839)" ed:togtopicid="183">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2199,1866)" ed:togtopicid="187">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1839,2272)" ed:togtopicid="195">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1852,2899)" ed:togtopicid="203">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1933,2812)" ed:togtopicid="205">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1933,3037)" ed:togtopicid="207">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2049,2737)" ed:togtopicid="209">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2059,2874)" ed:togtopicid="211">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2018,2987)" ed:togtopicid="213">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2013,3074)" ed:togtopicid="215">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2194,2724)" ed:togtopicid="219">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2215,2862)" ed:togtopicid="231">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2163,2987)" ed:togtopicid="245">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2174,3062)" ed:togtopicid="254">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1965,3401)" ed:togtopicid="262">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2435,3160)" ed:togtopicid="264">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2377,3436)" ed:togtopicid="268">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2758,3323)" ed:togtopicid="270">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2746,3565)" ed:togtopicid="272">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1854,3912)" ed:togtopicid="280">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1866,4229)" ed:togtopicid="282">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2007,3912)" ed:togtopicid="284">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2019,4229)" ed:togtopicid="286">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2012,4427)" ed:togtopicid="292">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2184,4454)" ed:togtopicid="298">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2570,4440)" ed:togtopicid="302">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2594,4476)" ed:togtopicid="304">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1938,4644)" ed:togtopicid="310">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2118,4538)" ed:togtopicid="314">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2118,4613)" ed:togtopicid="318">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2106,4679)" ed:togtopicid="326">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2082,4706)" ed:togtopicid="330">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2106,4759)" ed:togtopicid="334">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2005,4842)" ed:togtopicid="336">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2073,4954)" ed:togtopicid="348">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(825,3238)" ed:togtopicid="362">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(813,3355)" ed:togtopicid="364">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(669,3292)" ed:togtopicid="370">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(681,3319)" ed:togtopicid="374">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(645,3382)" ed:togtopicid="378">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(878,3471)" ed:togtopicid="386">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(821,2500)" ed:togtopicid="399">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(809,2863)" ed:togtopicid="405">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(833,1557)" ed:togtopicid="422">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(849,1647)" ed:togtopicid="430">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(849,1736)" ed:togtopicid="432">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(837,1824)" ed:togtopicid="434">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(757,2048)" ed:togtopicid="452">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(541,2093)" ed:togtopicid="458">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(764,2320)" ed:togtopicid="472">
        <use xlink:href="#minus"/>
    </g>
</svg>
</div>
        <div id="copyright">Created With  <a href="https://www.edrawsoft.com/" target="_blank" title="edrawsoft">MindMaster</a></div>
      </div>
    </div>
    <script>eval(atob('dmFyIG11YT13aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudDsNCnZhciB1YT0obXVhLmluZGV4T2YoJ3J2OjExJykrbXVhLmluZGV4T2YoJ01TSUUnKSk+PTA7DQpkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc3ZnLWNvbnRhaW5lcicpLm9uY29udGV4dG1lbnUgPSBmdW5jdGlvbiAoZXZlbnQpIHsNCiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOw0KfQ0KZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3N2Zy1jb250YWluZXInKS5vbm1vdXNlZG93biA9IGZ1bmN0aW9uIChldmVudCkgew0KICAgIGlmKGV2ZW50LndoaWNoID09Myl7DQogICAgICAgIHRoaXMuc3R5bGUuY3Vyc29yID0gJ3BvaW50ZXInOw0KICAgICAgICB0aGlzLm9ubW91c2Vtb3ZlID0gZnVuY3Rpb24gKGV2KSB7DQogICAgICAgICAgICB0aGlzLnNjcm9sbEJ5KC0oZXYubW92ZW1lbnRYKSwgMCk7DQogICAgICAgICAgICB3aW5kb3cuc2Nyb2xsQnkoMCwtKGV2Lm1vdmVtZW50WSkpDQogICAgICAgIH0NCiAgICAgICAgdGhpcy5vbm1vdXNldXAgPSBmdW5jdGlvbiAoKSB7DQogICAgICAgICAgICB0aGlzLnN0eWxlLmN1cnNvciA9ICBudWxsOw0KICAgICAgICAgICAgdGhpcy5vbm1vdXNldXAgPSBudWxsOw0KICAgICAgICAgICAgdGhpcy5vbm1vdXNlbW92ZSA9IG51bGw7DQogICAgICAgIH0NCiAgICB9DQp9DQpOdW1iZXIucHJvdG90eXBlLnRvc3VpdHN2Zz1mdW5jdGlvbiAoKSB7DQogICAgdmFyIG51bT10aGlzLnZhbHVlT2YoKTsNCiAgICBpZihudW0lMT09PTApew0KICAgICAgICByZXR1cm4gbnVtKzAuNQ0KICAgIH1lbHNlIHJldHVybiBudW07DQp9Ow0KTnVtYmVyLnByb3RvdHlwZS5wbHVzej1mdW5jdGlvbigpIHsNCiAgICB2YXIgbnVtPXRoaXMudmFsdWVPZigpOw0KICAgIHJldHVybiBudW08MTA/JzAnK251bTpudW07DQp9Ow0KZnVuY3Rpb24gcGFyc2VEYXRlKG51bSkgew0KICAgIHZhciBkYXRlID0gbmV3IERhdGUobnVtKTsNCiAgICB2YXIgWSA9IGRhdGUuZ2V0RnVsbFllYXIoKSArICctJzsNCiAgICB2YXIgTSA9IChkYXRlLmdldE1vbnRoKCkrMSkucGx1c3ooKSArICctJzsNCiAgICB2YXIgRCA9IGRhdGUuZ2V0RGF0ZSgpLnBsdXN6KCkgKyAnICc7DQogICAgdmFyIGggPSBkYXRlLmdldEhvdXJzKCkucGx1c3ooKSArICc6JzsNCiAgICB2YXIgbW0gPSBkYXRlLmdldE1pbnV0ZXMoKS5wbHVzeigpICsgJzonOw0KICAgIHZhciBzID0gZGF0ZS5nZXRTZWNvbmRzKCkucGx1c3ooKTsNCiAgICByZXR1cm4gWStNK0QraCttbStzOw0KfQ0KLy8tLXByZWRlZmluZWQNCi8vY29tbWVudC0tDQp2YXIgY29tbWVudHM9ZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnZz5nW2VkXFw6Y29tbWVudF0nKTsNCmZ1bmN0aW9uIGdldGN3aChwb3B1cCkgew0KICAgIGRvY3VtZW50LmJvZHkuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ3N2ZycpWzBdLmFwcGVuZENoaWxkKHBvcHVwKTsNCiAgICB2YXIgdz1wb3B1cC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aDsNCiAgICB2YXIgaD1wb3B1cC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5oZWlnaHQ7DQogICAgcmV0dXJuIFt3LGhdDQp9DQpmb3IodmFyIGk9MDtpPGNvbW1lbnRzLmxlbmd0aDtpKyspew0KICAgIHZhciBwb3B1cD1kb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJywnZycpOw0KICAgIHZhciBwb3B1cFI9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCdyZWN0Jyk7DQogICAgdmFyIGhvdmVyPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCdyZWN0Jyk7DQogICAgdmFyIG9saW5lPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCdyZWN0Jyk7DQogICAgaG92ZXIuc2V0QXR0cmlidXRlKCdmaWxsJywnI2NkY2RmZicpOw0KICAgIGhvdmVyLnNldEF0dHJpYnV0ZSgneCcsJzAnKTsNCiAgICBob3Zlci5zZXRBdHRyaWJ1dGUoJ3knLCcwJyk7DQogICAgaG92ZXIuc2V0QXR0cmlidXRlKCdoZWlnaHQnLCcxNicpOw0KICAgIGhvdmVyLnNldEF0dHJpYnV0ZSgnd2lkdGgnLCcxNicpOw0KICAgIGhvdmVyLnNldEF0dHJpYnV0ZSgnZmlsbC1vcGFjaXR5JywnMC42Jyk7DQogICAgaG92ZXIuc2V0QXR0cmlidXRlKCd0cmFuc2Zvcm0nLGNvbW1lbnRzW2ldLnF1ZXJ5U2VsZWN0b3IoJ3VzZScpLmdldEF0dHJpYnV0ZSgndHJhbnNmb3JtJykpOw0KICAgIGhvdmVyLnN0eWxlLmRpc3BsYXk9J25vbmUnOw0KICAgIGNvbW1lbnRzW2ldLmFwcGVuZENoaWxkKGhvdmVyKTsNCiAgICB2YXIgYT1KU09OLnBhcnNlKGNvbW1lbnRzW2ldLmdldEF0dHJpYnV0ZSgnZWQ6Y29tbWVudCcpKTsNCiAgICB2YXIgaGVpZ2h0PTA7DQogICAgdmFyIGNhcnI9W107DQogICAgZm9yKHZhciBqPTA7ajxhLmxlbmd0aDtqKyspew0KICAgICAgICB2YXIgc3RhbXA9TnVtYmVyKGFbal0uRGF0ZSkqMTAwMDsNCiAgICAgICAgdmFyIHRpbWU9cGFyc2VEYXRlKHN0YW1wKTsNCiAgICAgICAgdmFyIG5hbWU9YVtqXS5OYW1lOw0KICAgICAgICB2YXIgbWVzc2FnZT1hW2pdLk1lc3NhZ2U7DQogICAgICAgIHZhciBtZXNzYWdlQXJyPW1lc3NhZ2Uuc3BsaXQoL1xuLyk7DQogICAgICAgIHZhciBvPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCdnJyk7DQogICAgICAgIHZhciBuPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCd0ZXh0Jyk7DQogICAgICAgIHZhciB0PWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCd0ZXh0Jyk7DQogICAgICAgIHZhciBtPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCd0ZXh0Jyk7DQogICAgICAgIG4uc2V0QXR0cmlidXRlKCd4Jyw1KTsNCiAgICAgICAgbi5zZXRBdHRyaWJ1dGUoJ3knLDEyKTsNCiAgICAgICAgbi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCcjMDA2ZWZmJyk7DQogICAgICAgIG4udGV4dENvbnRlbnQ9bmFtZSsnOiAnOw0KICAgICAgICBuLnNldEF0dHJpYnV0ZSgnZm9udC1zaXplJywnMTInKTsNCiAgICAgICAgdC5zZXRBdHRyaWJ1dGUoJ3gnLDIwMCk7DQogICAgICAgIHQuc2V0QXR0cmlidXRlKCd5JywxMik7DQogICAgICAgIHQuc2V0QXR0cmlidXRlKCdmaWxsJywnIzk2OTY5NicpOw0KICAgICAgICB0LnRleHRDb250ZW50PXRpbWU7DQogICAgICAgIHQuc2V0QXR0cmlidXRlKCdmb250LXNpemUnLCcxMCcpOw0KICAgICAgICBtLnNldEF0dHJpYnV0ZSgndHJhbnNmb3JtJywndHJhbnNsYXRlKDIwLDI3KScpOw0KICAgICAgICBtLnNldEF0dHJpYnV0ZSgnZm9udC1zaXplJywnMTInKTsNCiAgICAgICAgZm9yKHZhciBrPTA7azxtZXNzYWdlQXJyLmxlbmd0aDtrKyspew0KICAgICAgICAgICAgdmFyIHRzPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCd0c3BhbicpOw0KICAgICAgICAgICAgdHMuc2V0QXR0cmlidXRlKCd4JywnMCcpOw0KICAgICAgICAgICAgdHMuc2V0QXR0cmlidXRlKCd5JyxrKjE2KTsNCiAgICAgICAgICAgIHRzLnRleHRDb250ZW50PW1lc3NhZ2VBcnJba107DQogICAgICAgICAgICBtLmFwcGVuZENoaWxkKHRzKTsNCiAgICAgICAgfQ0KICAgICAgICBvLnNldEF0dHJpYnV0ZSgndHJhbnNmb3JtJywndHJhbnNsYXRlKDAsJytoZWlnaHQrJyknKTsNCiAgICAgICAgby5hcHBlbmRDaGlsZChuKTsNCiAgICAgICAgby5hcHBlbmRDaGlsZCh0KTsNCiAgICAgICAgby5hcHBlbmRDaGlsZChtKTsNCiAgICAgICAgY2Fyci5wdXNoKG8pOw0KICAgICAgICBwb3B1cC5hcHBlbmRDaGlsZChvKTsNCiAgICAgICAgaGVpZ2h0PShtZXNzYWdlQXJyLmxlbmd0aCsxKSoxNitoZWlnaHQ7DQogICAgfQ0KICAgIHZhciB3YXJyPWdldGN3aChwb3B1cCk7DQogICAgb2xpbmUuc2V0QXR0cmlidXRlKCd4JywnMCcpOw0KICAgIG9saW5lLnNldEF0dHJpYnV0ZSgneScsJzAnKTsNCiAgICB2YXIgb3c9d2FyclswXSsxMC41Ow0KICAgIHZhciBvaD13YXJyWzFdKzM7DQogICAgb2xpbmUuc2V0QXR0cmlidXRlKCd3aWR0aCcsb3cpOw0KICAgIG9saW5lLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JyxvaCk7DQogICAgb2xpbmUuc2V0QXR0cmlidXRlKCdmaWxsJywnd2hpdGUnKTsNCiAgICBvbGluZS5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsJyM2NTY1NjUnKTsNCiAgICBwb3B1cC5hcHBlbmRDaGlsZChvbGluZSk7DQogICAgdmFyIGw9Y2Fyci5sZW5ndGg7DQogICAgd2hpbGUobC0tKXsNCiAgICAgICAgcG9wdXAuYXBwZW5kQ2hpbGQoY2FycltsXSk7DQogICAgfQ0KICAgIHBvcHVwLm9ubW91c2VvdmVyPWZ1bmN0aW9uICgpIHsNCiAgICAgICAgdGhpcy5zdHlsZS5kaXNwbGF5PSdibG9jayc7DQogICAgfTsNCiAgICBwb3B1cC5vbm1vdXNlb3V0PWZ1bmN0aW9uICgpIHsNCiAgICAgICAgdGhpcy5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnOw0KICAgIH07DQogICAgdmFyIGNzPWNvbW1lbnRzW2ldLnF1ZXJ5U2VsZWN0b3IoJ3VzZScpLmdldEF0dHJpYnV0ZSgndHJhbnNmb3JtJykubWF0Y2goL1woKFxTKnxcUypcc1xTKilcKS8pWzFdLnNwbGl0KC8gfCwvKTsNCiAgICB2YXIgcHM9Y29tbWVudHNbaV0ucGFyZW50Tm9kZS5nZXRBdHRyaWJ1dGUoJ3RyYW5zZm9ybScpOw0KICAgIGlmKHBzLnN1YnN0cigwLDIpID09ICd0cicpew0KICAgICAgICB2YXIgcHBzID0gcHMubWF0Y2goL1woKFxTKnxcUypcc1xTKilcKS8pWzFdLnNwbGl0KC8gfCwvKTsNCiAgICAgICAgdmFyIHg9cGFyc2VGbG9hdChjc1swXSkrcGFyc2VGbG9hdChwcHNbMF0pOw0KICAgICAgICB2YXIgeT1wYXJzZUZsb2F0KHBwc1sxXSk7DQogICAgICAgIHg9eC50b3N1aXRzdmcoKTsNCiAgICAgICAgeT15LnRvc3VpdHN2ZygpOw0KICAgICAgICB2YXIgdHJzdHIgPSAndHJhbnNsYXRlKCcreCsnLCcreSsnKSc7DQogICAgfQ0KICAgIGVsc2UgaWYocHMuc3Vic3RyKDAsMikgPT0gJ21hJyl7DQogICAgICAgIHZhciBwcHMgPSBwcy5tYXRjaCgvKFwtP1xkKyhcLlxkKyk/KVtcLCBdKFwtP1xkKyhcLlxkKyk/KVtcLCBdKFwtP1xkKyhcLlxkKyk/KVtcLCBdKFwtP1xkKyhcLlxkKyk/KVtcLCBdKFwtP1xkKyhcLlxkKyk/KVtcLCBdKFwtP1xkKyhcLlxkKyk/KVwpJC8pOw0KICAgICAgICB2YXIgbWFBcnIgPSBbcGFyc2VGbG9hdChwcHNbMV0pLHBhcnNlRmxvYXQocHBzWzNdKSxwYXJzZUZsb2F0KHBwc1s1XSkscGFyc2VGbG9hdChwcHNbN10pLHBhcnNlRmxvYXQocHBzWzldKSxwYXJzZUZsb2F0KHBwc1sxMV0pXTsNCiAgICAgICAgaWYobWFBcnJbMV0gPT0gMCl7DQogICAgICAgICAgICB2YXIgeCA9IHBhcnNlRmxvYXQoY3NbMF0pOw0KICAgICAgICAgICAgdmFyIHk9IHBhcnNlRmxvYXQoY3NbMV0pKzE2Ow0KICAgICAgICAgICAgdmFyIHgxID0geCAqIG1hQXJyWzBdICsgeSAqIG1hQXJyWzJdICsgbWFBcnJbNF07DQogICAgICAgICAgICB2YXIgeTEgPSB4ICogbWFBcnJbMV0gKyB5ICogbWFBcnJbM10gKyBtYUFycls1XTsNCiAgICAgICAgICAgIHgxPXgxLnRvc3VpdHN2ZygpOw0KICAgICAgICAgICAgeTE9eTEudG9zdWl0c3ZnKCk7DQogICAgICAgICAgICB2YXIgdHJzdHIgPSAgJ3RyYW5zbGF0ZSgnK3gxKycsJyt5MSsnKSc7DQogICAgICAgIH1lbHNlew0KICAgICAgICAgICAgdmFyIHggPSBwYXJzZUZsb2F0KGNzWzBdKSsxNjsNCiAgICAgICAgICAgIHZhciB5ID0gcGFyc2VGbG9hdChjc1sxXSkrMTY7DQogICAgICAgICAgICB2YXIgeDEgPSB4ICogbWFBcnJbMF0gKyB5ICogbWFBcnJbMl0gKyBtYUFycls0XTsNCiAgICAgICAgICAgIHZhciB5MSA9IHggKiBtYUFyclsxXSArIHkgKiBtYUFyclszXSArIG1hQXJyWzVdOw0KICAgICAgICAgICAgeCA9IHBhcnNlRmxvYXQoY3NbMF0pKzE2Ow0KICAgICAgICAgICAgeSA9IHBhcnNlRmxvYXQoY3NbMV0pOw0KICAgICAgICAgICAgdmFyIHgyID0geCAqIG1hQXJyWzBdICsgeSAqIG1hQXJyWzJdICsgbWFBcnJbNF07DQogICAgICAgICAgICB2YXIgeTIgPSB4ICogbWFBcnJbMV0gKyB5ICogbWFBcnJbM10gKyBtYUFycls1XTsNCiAgICAgICAgICAgIHZhciBmeCA9IHgxPHgyP3gxLnRvc3VpdHN2ZygpOiB4Mi50b3N1aXRzdmcoKTsNCiAgICAgICAgICAgIHZhciBmeSA9IHkxPnkyP3kxLnRvc3VpdHN2ZygpOiB5Mi50b3N1aXRzdmcoKTsNCiAgICAgICAgICAgIHZhciBvZmZ5ID0gTWF0aC5hYnMoeTEteTIpOw0KICAgICAgICAgICAgdmFyIHRyc3RyID0gICd0cmFuc2xhdGUoJytmeCsnLCcrZnkrJyknOw0KICAgICAgICAgICAgcG9wdXBSLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JyxvZmZ5LnRvU3RyaW5nKCkpOw0KICAgICAgICAgICAgcG9wdXBSLnNldEF0dHJpYnV0ZSgnd2lkdGgnLCcxNicpOw0KICAgICAgICAgICAgcG9wdXBSLnNldEF0dHJpYnV0ZSgneScsKC1vZmZ5KS50b1N0cmluZygpKTsNCiAgICAgICAgICAgIHBvcHVwUi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCd0cmFuc3BhcmVudCcpOw0KICAgICAgICAgICAgcG9wdXAuYXBwZW5kQ2hpbGQocG9wdXBSKTsNCiAgICAgICAgfQ0KICAgIH0NCiAgICBwb3B1cC5zZXRBdHRyaWJ1dGUoJ3RyYW5zZm9ybScsdHJzdHIpOw0KICAgIHBvcHVwLnNldEF0dHJpYnV0ZSgnY29tbWVudCcsJycpOw0KICAgIHBvcHVwLnN0eWxlLmRpc3BsYXk9J25vbmUnOw0KICAgIHBvcHVwLnNldEF0dHJpYnV0ZSgnZWQ6Y29tbWVudGlkJyxjb21tZW50c1tpXS5wYXJlbnROb2RlLmlkKTsNCiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjc3ZnLWNvbnRhaW5lciA+IHN2ZycpLmFwcGVuZENoaWxkKHBvcHVwKTsNCiAgICBjb21tZW50c1tpXS5vbm1vdXNlb3Zlcj1mdW5jdGlvbiAoKSB7DQogICAgICAgIHZhciBjb21tZW50aWQ9dGhpcy5wYXJlbnROb2RlLmlkOw0KICAgICAgICB0aGlzLnF1ZXJ5U2VsZWN0b3IoJ3JlY3QnKS5zdHlsZS5kaXNwbGF5PSdibG9jayc7DQogICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoImdbZWRcXDpjb21tZW50aWQ9JyIrY29tbWVudGlkKyInXVtjb21tZW50XSIpLnN0eWxlLmRpc3BsYXk9J2Jsb2NrJzsNCiAgICB9Ow0KICAgIGNvbW1lbnRzW2ldLm9ubW91c2VvdXQ9ZnVuY3Rpb24gKCkgew0KICAgICAgICB2YXIgY29tbWVudGlkPXRoaXMucGFyZW50Tm9kZS5pZDsNCi8vICAgICAgICB3aW5kb3cuZ2V0U2VsZWN0aW9uKCkucmVtb3ZlQWxsUmFuZ2VzKCk7DQogICAgICAgIHRoaXMucXVlcnlTZWxlY3RvcigncmVjdCcpLnN0eWxlLmRpc3BsYXk9J25vbmUnOw0KICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCJnW2VkXFw6Y29tbWVudGlkPSciK2NvbW1lbnRpZCsiJ11bY29tbWVudF0iKS5zdHlsZS5kaXNwbGF5PSdub25lJzsNCiAgICB9DQp9DQovLy0tY29tbWVudA0KLy9ub3RlLS0NCmlmKCF1YSl7DQogICAgdmFyIG5vdGVzPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2c+Z1tlZFxcOm5vdGVdJyk7DQogICAgZnVuY3Rpb24gZ2V0d2gocyxwKSB7DQogICAgICAgIHZhciBtYWlucD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTsNCiAgICAgICAgbWFpbnAuc3R5bGUuY3NzVGV4dD1zOw0KICAgICAgICBtYWlucC5zdHlsZS5kaXNwbGF5PSdpbmxpbmUtYmxvY2snOw0KCQltYWlucC5zdHlsZS5tYXhXaWR0aCA9ICc0MDBweCc7DQoJCW1haW5wLnN0eWxlLndvcmRCcmVhayA9ICdicmVhay1hbGwnOw0KICAgICAgICBtYWlucC5pbm5lckhUTUw9cDsNCiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChtYWlucCk7DQogICAgICAgIHZhciB3PW1haW5wLmNsaWVudFdpZHRoOw0KICAgICAgICB2YXIgaD1tYWlucC5jbGllbnRIZWlnaHQ7DQogICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQobWFpbnApOw0KICAgICAgICByZXR1cm4gW3csaF0NCiAgICB9DQogICAgZm9yKHZhciBpPTA7aTxub3Rlcy5sZW5ndGg7aSsrKXsNCiAgICAgICAgdmFyIGE9bm90ZXNbaV0uZ2V0QXR0cmlidXRlKCdlZDpub3RlJyk7DQoJCXZhciBub3RlTG9jayA9IG5vdGVzW2ldLmdldEF0dHJpYnV0ZSgnZWQ6bm90ZWxvY2snKTsNCiAgICAgICAgaWYobm90ZUxvY2sgPT0gJ3RydWUnKXsNCiAgICAgICAgICAgIGNvbnRpbnVlOw0KICAgICAgICB9DQogICAgICAgIHZhciBtYWlucD1hLm1hdGNoKC88Ym9keVtePl0qPiguKik8XC9ib2R5Pi8pWzFdOw0KICAgICAgICB2YXIgbWFpbnM9YS5tYXRjaCgvc3R5bGU9IiguKj8pIi8pWzFdOw0KICAgICAgICB2YXIgb3V0PWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCdnJyk7DQogICAgICAgIHZhciBvbGluZT1kb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJywncmVjdCcpOw0KICAgICAgICB2YXIgcG9wdXA9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsJ2ZvcmVpZ25PYmplY3QnKTsNCiAgICAgICAgdmFyIHBvcHVwUj0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsJ3JlY3QnKTsNCiAgICAgICAgdmFyIGhvdmVyPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCdyZWN0Jyk7DQogICAgICAgIGhvdmVyLnNldEF0dHJpYnV0ZSgnZmlsbCcsJyNjZGNkZmYnKTsNCiAgICAgICAgaG92ZXIuc2V0QXR0cmlidXRlKCd4JywnMCcpOw0KICAgICAgICBob3Zlci5zZXRBdHRyaWJ1dGUoJ3knLCcwJyk7DQogICAgICAgIGhvdmVyLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywnMTYnKTsNCiAgICAgICAgaG92ZXIuc2V0QXR0cmlidXRlKCd3aWR0aCcsJzE2Jyk7DQogICAgICAgIGhvdmVyLnNldEF0dHJpYnV0ZSgnZmlsbC1vcGFjaXR5JywnMC42Jyk7DQogICAgICAgIGhvdmVyLnNldEF0dHJpYnV0ZSgndHJhbnNmb3JtJyxub3Rlc1tpXS5xdWVyeVNlbGVjdG9yKCd1c2UnKS5nZXRBdHRyaWJ1dGUoJ3RyYW5zZm9ybScpKTsNCiAgICAgICAgaG92ZXIuc3R5bGUuZGlzcGxheT0nbm9uZSc7DQogICAgICAgIG5vdGVzW2ldLmFwcGVuZENoaWxkKGhvdmVyKTsNCiAgICAgICAgcG9wdXAuc3R5bGUuY3NzVGV4dD1tYWluczsNCiAgICAgICAgcG9wdXAuaW5uZXJIVE1MPW1haW5wOw0KICAgICAgICB2YXIgd2g9Z2V0d2gobWFpbnMsbWFpbnApOw0KICAgICAgICBwb3B1cC5zZXRBdHRyaWJ1dGUoJ3dpZHRoJyx3aFswXSk7DQogICAgICAgIHBvcHVwLnNldEF0dHJpYnV0ZSgnaGVpZ2h0Jyx3aFsxXSk7DQogICAgICAgIHBvcHVwLnNldEF0dHJpYnV0ZSgndHJhbnNmb3JtJywndHJhbnNsYXRlKDgsNCknKTsNCgkJcG9wdXAuc3R5bGUud29yZEJyZWFrID0gJ2JyZWFrLWFsbCc7DQogICAgICAgIHBvcHVwLnN0eWxlLnRleHRBbGlnbj0nbGVmdCc7DQogICAgICAgIG9saW5lLnNldEF0dHJpYnV0ZSgneCcsJzAnKTsNCiAgICAgICAgb2xpbmUuc2V0QXR0cmlidXRlKCd5JywnMCcpOw0KICAgICAgICBvbGluZS5zZXRBdHRyaWJ1dGUoJ3dpZHRoJyx3aFswXSsxNik7DQogICAgICAgIG9saW5lLnNldEF0dHJpYnV0ZSgnaGVpZ2h0Jyx3aFsxXSs4KTsNCiAgICAgICAgb2xpbmUuc2V0QXR0cmlidXRlKCdzdHJva2UnLCcjYTI3YTAwJyk7DQogICAgICAgIG9saW5lLnNldEF0dHJpYnV0ZSgnZmlsbCcsJyNmZmU3OWQnKTsNCiAgICAgICAgb3V0LmFwcGVuZENoaWxkKG9saW5lKTsNCiAgICAgICAgb3V0LmFwcGVuZENoaWxkKHBvcHVwKTsNCiAgICAgICAgb3V0LnNldEF0dHJpYnV0ZSgnbm90ZScsJycpOw0KICAgICAgICBvdXQuc3R5bGUuZGlzcGxheT0nbm9uZSc7DQogICAgICAgIG91dC5zZXRBdHRyaWJ1dGUoJ2VkOm5vdGVpZCcsbm90ZXNbaV0ucGFyZW50Tm9kZS5pZCk7DQogICAgICAgIG91dC5vbm1vdXNlb3Zlcj1mdW5jdGlvbiAoKSB7DQogICAgICAgICAgICB0aGlzLnN0eWxlLmRpc3BsYXk9J2Jsb2NrJzsNCiAgICAgICAgfTsNCiAgICAgICAgb3V0Lm9ubW91c2VvdXQ9ZnVuY3Rpb24gKCkgew0KLy8gICAgICAgIHdpbmRvdy5nZXRTZWxlY3Rpb24gPyB3aW5kb3cuZ2V0U2VsZWN0aW9uKCkucmVtb3ZlUmFuZ2Uod2luZG93LmdldFNlbGVjdGlvbigpLnJlKTpkb2N1bWVudC5zZWxlY3Rpb24uZW1wdHkoKTsNCg0KICAgICAgICAgICAgdGhpcy5zdHlsZS5kaXNwbGF5PSdub25lJzsNCiAgICAgICAgfTsNCiAgICAgICAgdmFyIGNzPW5vdGVzW2ldLnF1ZXJ5U2VsZWN0b3IoJ3VzZScpLmdldEF0dHJpYnV0ZSgndHJhbnNmb3JtJykubWF0Y2goL1woKFxTKnxcUypcc1xTKilcKS8pWzFdLnNwbGl0KC8gfCwvKTsNCiAgICAgICAgdmFyIHBzPW5vdGVzW2ldLnBhcmVudE5vZGUuZ2V0QXR0cmlidXRlKCd0cmFuc2Zvcm0nKTsNCiAgICAgICAgaWYocHMuc3Vic3RyKDAsMikgPT0gJ3RyJyl7DQogICAgICAgICAgICB2YXIgcHBzID0gcHMubWF0Y2goL1woKFxTKnxcUypcc1xTKilcKS8pWzFdLnNwbGl0KC8gfCwvKTsNCiAgICAgICAgICAgIHZhciB4PXBhcnNlRmxvYXQoY3NbMF0pK3BhcnNlRmxvYXQocHBzWzBdKTsNCiAgICAgICAgICAgIHZhciB5PXBhcnNlRmxvYXQocHBzWzFdKTsNCiAgICAgICAgICAgIHg9eC50b3N1aXRzdmcoKTsNCiAgICAgICAgICAgIHk9eS50b3N1aXRzdmcoKTsNCiAgICAgICAgICAgIHZhciB0cnN0ciA9ICd0cmFuc2xhdGUoJyt4KycsJyt5KycpJzsNCiAgICAgICAgfWVsc2UgaWYocHMuc3Vic3RyKDAsMikgPT0gJ21hJyl7DQogICAgICAgICAgICB2YXIgcHBzID0gcHMubWF0Y2goLyhcLT9cZCsoXC5cZCspPylbXCwgXShcLT9cZCsoXC5cZCspPylbXCwgXShcLT9cZCsoXC5cZCspPylbXCwgXShcLT9cZCsoXC5cZCspPylbXCwgXShcLT9cZCsoXC5cZCspPylbXCwgXShcLT9cZCsoXC5cZCspPylcKSQvKTsNCiAgICAgICAgICAgIHZhciBtYUFyciA9IFtwYXJzZUZsb2F0KHBwc1sxXSkscGFyc2VGbG9hdChwcHNbM10pLHBhcnNlRmxvYXQocHBzWzVdKSxwYXJzZUZsb2F0KHBwc1s3XSkscGFyc2VGbG9hdChwcHNbOV0pLHBhcnNlRmxvYXQocHBzWzExXSldOw0KICAgICAgICAgICAgaWYobWFBcnJbMV0gPT0gMCl7DQogICAgICAgICAgICAgICAgdmFyIHggPSBwYXJzZUZsb2F0KGNzWzBdKTsNCiAgICAgICAgICAgICAgICB2YXIgeSA9IHBhcnNlRmxvYXQoY3NbMV0pKzE2Ow0KICAgICAgICAgICAgICAgIHZhciB4MSA9IHggKiBtYUFyclswXSArIHkgKiBtYUFyclsyXSArIG1hQXJyWzRdOw0KICAgICAgICAgICAgICAgIHZhciB5MSA9IHggKiBtYUFyclsxXSArIHkgKiBtYUFyclszXSArIG1hQXJyWzVdOw0KICAgICAgICAgICAgICAgIHgxPXgxLnRvc3VpdHN2ZygpOw0KICAgICAgICAgICAgICAgIHkxPXkxLnRvc3VpdHN2ZygpOw0KICAgICAgICAgICAgICAgIHZhciB0cnN0ciA9ICAndHJhbnNsYXRlKCcreDErJywnK3kxKycpJzsNCiAgICAgICAgICAgIH1lbHNlew0KICAgICAgICAgICAgICAgIHZhciB4ID0gcGFyc2VGbG9hdChjc1swXSkrMTY7DQogICAgICAgICAgICAgICAgdmFyIHkgPSBwYXJzZUZsb2F0KGNzWzFdKSsxNjsNCiAgICAgICAgICAgICAgICB2YXIgeDEgPSB4ICogbWFBcnJbMF0gKyB5ICogbWFBcnJbMl0gKyBtYUFycls0XTsNCiAgICAgICAgICAgICAgICB2YXIgeTEgPSB4ICogbWFBcnJbMV0gKyB5ICogbWFBcnJbM10gKyBtYUFycls1XTsNCiAgICAgICAgICAgICAgICB4ID0gcGFyc2VGbG9hdChjc1swXSkrMTY7DQogICAgICAgICAgICAgICAgeSA9IHBhcnNlRmxvYXQoY3NbMV0pOw0KICAgICAgICAgICAgICAgIHZhciB4MiA9IHggKiBtYUFyclswXSArIHkgKiBtYUFyclsyXSArIG1hQXJyWzRdOw0KICAgICAgICAgICAgICAgIHZhciB5MiA9IHggKiBtYUFyclsxXSArIHkgKiBtYUFyclszXSArIG1hQXJyWzVdOw0KICAgICAgICAgICAgICAgIHZhciBmeCA9IHgxPHgyP3gxLnRvc3VpdHN2ZygpOiB4Mi50b3N1aXRzdmcoKTsNCiAgICAgICAgICAgICAgICB2YXIgZnkgPSB5MT55Mj95MS50b3N1aXRzdmcoKTogeTIudG9zdWl0c3ZnKCk7DQoJCQkJdmFyIG9mZnkgPSBNYXRoLmFicyh5MS15Mik7CQkJCQkJCQkJCSAgDQogICAgICAgICAgICAgICAgdmFyIHRyc3RyID0gICd0cmFuc2xhdGUoJytmeCsnLCcrZnkrJyknOw0KICAgICAgICAgICAgICAgIHBvcHVwUi5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsb2ZmeS50b1N0cmluZygpKTsNCiAgICAgICAgICAgICAgICBwb3B1cFIuc2V0QXR0cmlidXRlKCd3aWR0aCcsJzE2Jyk7DQogICAgICAgICAgICAgICAgcG9wdXBSLnNldEF0dHJpYnV0ZSgneScsKC1vZmZ5KS50b1N0cmluZygpKTsNCiAgICAgICAgICAgICAgICBwb3B1cFIuc2V0QXR0cmlidXRlKCdmaWxsJywndHJhbnNwYXJlbnQnKTsNCiAgICAgICAgICAgICAgICBwb3B1cC5hcHBlbmRDaGlsZChwb3B1cFIpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIG91dC5zZXRBdHRyaWJ1dGUoJ3RyYW5zZm9ybScsdHJzdHIpOw0KICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjc3ZnLWNvbnRhaW5lciA+IHN2ZycpLmFwcGVuZENoaWxkKG91dCk7DQogICAgICAgIG5vdGVzW2ldLm9ubW91c2VvdmVyPWZ1bmN0aW9uICgpIHsNCiAgICAgICAgICAgIHZhciBub3RlaWQ9dGhpcy5wYXJlbnROb2RlLmlkOw0KICAgICAgICAgICAgdGhpcy5xdWVyeVNlbGVjdG9yKCdyZWN0Jykuc3R5bGUuZGlzcGxheT0nYmxvY2snOw0KICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiZ1tlZFxcOm5vdGVpZD0nIitub3RlaWQrIiddW25vdGVdIikuc3R5bGUuZGlzcGxheT0nYmxvY2snOw0KICAgICAgICB9Ow0KICAgICAgICBub3Rlc1tpXS5vbm1vdXNlb3V0PWZ1bmN0aW9uICgpIHsNCiAgICAgICAgICAgIHZhciBub3RlaWQ9dGhpcy5wYXJlbnROb2RlLmlkOw0KLy8gICAgICAgIHdpbmRvdy5nZXRTZWxlY3Rpb24oKS5yZW1vdmVBbGxSYW5nZXMoKTsNCiAgICAgICAgICAgIHRoaXMucXVlcnlTZWxlY3RvcigncmVjdCcpLnN0eWxlLmRpc3BsYXk9J25vbmUnOw0KICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiZ1tlZFxcOm5vdGVpZD0nIitub3RlaWQrIiddW25vdGVdIikuc3R5bGUuZGlzcGxheT0nbm9uZSc7DQogICAgICAgIH0NCiAgICB9DQp9ZWxzZXsNCiAgICBjb25zb2xlLmxvZygn5oqx5q2J77yMSUXmtY/op4jlmajkuI3mlK/mjIFub3Rl6Kej5p6Q77yM6K+35L2/55So5YW25LuW5YaF5qC45rWP6KeI5Zmo44CC6LCi6LCi77yBJykNCn0NCi8vLS1ub3RlDQovL2h5cGVybGluay0tDQp2YXIgbGlua3M9ZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnZz5nW2VkXFw6aHlwZXJsaW5rXScpOw0KZnVuY3Rpb24gZ2V0bWF4bGVuKGFycixicnIpIHsNCiAgICB2YXIgbD0wOw0KICAgIHZhciBsbD0wOw0KICAgIGZvcih2YXIgaj0wO2o8YXJyLmxlbmd0aDtqKyspew0KICAgICAgICB2YXIgZT1kb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJywndGV4dCcpOw0KICAgICAgICBpZighaXNOYU4obGlua2FycltqXSkpew0KICAgICAgICAgICAgZS50ZXh0Q29udGVudD0nUGFnZS0nK2FycltqXTsNCiAgICAgICAgfWVsc2V7DQogICAgICAgICAgICBlLnRleHRDb250ZW50PWFycltqXTsNCiAgICAgICAgfQ0KICAgICAgICBlLnN0eWxlLmZvbnRTaXplPScxMnB4JzsNCiAgICAgICAgZG9jdW1lbnQuYm9keS5nZXRFbGVtZW50c0J5VGFnTmFtZSgnc3ZnJylbMF0uYXBwZW5kQ2hpbGQoZSk7DQogICAgICAgIHZhciBldz1lLmdldEJCb3goKS53aWR0aDsNCiAgICAgICAgZG9jdW1lbnQuYm9keS5nZXRFbGVtZW50c0J5VGFnTmFtZSgnc3ZnJylbMF0ucmVtb3ZlQ2hpbGQoZSk7DQogICAgICAgIHZhciBoPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCd0ZXh0Jyk7DQogICAgICAgIGgudGV4dENvbnRlbnQ9YnJyW2pdOw0KICAgICAgICBoLnN0eWxlLmZvbnRTaXplPScxMnB4JzsNCiAgICAgICAgaC5zdHlsZS5mb250V2VpZ2h0PSdib2xkJzsNCiAgICAgICAgZG9jdW1lbnQuYm9keS5nZXRFbGVtZW50c0J5VGFnTmFtZSgnc3ZnJylbMF0uYXBwZW5kQ2hpbGQoaCk7DQogICAgICAgIHZhciBodz1oLmdldEJCb3goKS53aWR0aDsNCiAgICAgICAgZG9jdW1lbnQuYm9keS5nZXRFbGVtZW50c0J5VGFnTmFtZSgnc3ZnJylbMF0ucmVtb3ZlQ2hpbGQoaCk7DQogICAgICAgIGw9ZXc+aHc/ZXc6aHc7DQogICAgICAgIGxsPWw+bGw/bDpsbDsNCiAgICB9DQogICAgcmV0dXJuIGxsOw0KfQ0KZm9yKHZhciBpPTA7aTxsaW5rcy5sZW5ndGg7aSsrKXsNCiAgICB2YXIgcG9wdXA9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsJ2cnKTsNCiAgICB2YXIgcG9wdXBSPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJywncmVjdCcpOw0KICAgIHZhciBob3Zlcj1kb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJywncmVjdCcpOw0KICAgIHZhciBkZXNjYXJyPVtdOw0KICAgIHZhciBsaW5rYXJyPVtdOw0KICAgIGhvdmVyLnNldEF0dHJpYnV0ZSgnZmlsbCcsJyNjZGNkZmYnKTsNCiAgICBob3Zlci5zZXRBdHRyaWJ1dGUoJ3gnLCcwJyk7DQogICAgaG92ZXIuc2V0QXR0cmlidXRlKCd5JywnMCcpOw0KICAgIGhvdmVyLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywnMTYnKTsNCiAgICBob3Zlci5zZXRBdHRyaWJ1dGUoJ3dpZHRoJywnMTYnKTsNCiAgICBob3Zlci5zZXRBdHRyaWJ1dGUoJ2ZpbGwtb3BhY2l0eScsJzAuNicpOw0KICAgIGhvdmVyLnNldEF0dHJpYnV0ZSgndHJhbnNmb3JtJyxsaW5rc1tpXS5xdWVyeVNlbGVjdG9yKCd1c2UnKS5nZXRBdHRyaWJ1dGUoJ3RyYW5zZm9ybScpKTsNCiAgICBob3Zlci5zdHlsZS5kaXNwbGF5PSdub25lJzsNCiAgICBsaW5rc1tpXS5hcHBlbmRDaGlsZChob3Zlcik7DQogICAgLy8gY29uc29sZS5sb2cobGlua3NbaV0uZ2V0QXR0cmlidXRlKCdlZDpoeXBlcmxpbmsnKSk7DQogICAgdmFyIGE9SlNPTi5wYXJzZShsaW5rc1tpXS5nZXRBdHRyaWJ1dGUoJ2VkOmh5cGVybGluaycpKTsNCiAgICB2YXIgY3M9bGlua3NbaV0ucXVlcnlTZWxlY3RvcigndXNlJykuZ2V0QXR0cmlidXRlKCd0cmFuc2Zvcm0nKS5tYXRjaCgvXCgoXFMqfFxTKlxzXFMqKVwpLylbMV0uc3BsaXQoLyB8LC8pOw0KICAgIHZhciBwcz1saW5rc1tpXS5wYXJlbnROb2RlLmdldEF0dHJpYnV0ZSgndHJhbnNmb3JtJyk7DQogICAgaWYocHMuc3Vic3RyKDAsMikgPT0gJ3RyJyl7DQogICAgICAgIHZhciBwcHMgPSBwcy5tYXRjaCgvXCgoXFMqfFxTKlxzXFMqKVwpLylbMV0uc3BsaXQoLyB8LC8pOw0KICAgICAgICB2YXIgeD1wYXJzZUZsb2F0KGNzWzBdKStwYXJzZUZsb2F0KHBwc1swXSk7DQogICAgICAgIHZhciB5PXBhcnNlRmxvYXQocHBzWzFdKTsNCiAgICAgICAgeD14LnRvc3VpdHN2ZygpOw0KICAgICAgICB5PXkudG9zdWl0c3ZnKCk7DQogICAgICAgIHZhciB0cnN0ciA9ICd0cmFuc2xhdGUoJyt4KycsJyt5KycpJzsNCiAgICB9ZWxzZSBpZihwcy5zdWJzdHIoMCwyKSA9PSAnbWEnKXsNCiAgICAgICAgdmFyIHBwcyA9IHBzLm1hdGNoKC8oXC0/XGQrKFwuXGQrKT8pW1wsIF0oXC0/XGQrKFwuXGQrKT8pW1wsIF0oXC0/XGQrKFwuXGQrKT8pW1wsIF0oXC0/XGQrKFwuXGQrKT8pW1wsIF0oXC0/XGQrKFwuXGQrKT8pW1wsIF0oXC0/XGQrKFwuXGQrKT8pXCkkLyk7DQogICAgICAgIHZhciBtYUFyciA9IFtwYXJzZUZsb2F0KHBwc1sxXSkscGFyc2VGbG9hdChwcHNbM10pLHBhcnNlRmxvYXQocHBzWzVdKSxwYXJzZUZsb2F0KHBwc1s3XSkscGFyc2VGbG9hdChwcHNbOV0pLHBhcnNlRmxvYXQocHBzWzExXSldOw0KICAgICAgICBpZihtYUFyclsxXSA9PSAwKXsNCiAgICAgICAgICAgIHZhciB4ID0gcGFyc2VGbG9hdChjc1swXSk7DQogICAgICAgICAgICB2YXIgeSA9IHBhcnNlRmxvYXQoY3NbMV0pKzE2Ow0KICAgICAgICAgICAgdmFyIHgxID0geCAqIG1hQXJyWzBdICsgeSAqIG1hQXJyWzJdICsgbWFBcnJbNF07DQogICAgICAgICAgICB2YXIgeTEgPSB4ICogbWFBcnJbMV0gKyB5ICogbWFBcnJbM10gKyBtYUFycls1XTsNCiAgICAgICAgICAgIHgxPXgxLnRvc3VpdHN2ZygpOw0KICAgICAgICAgICAgeTE9eTEudG9zdWl0c3ZnKCk7DQogICAgICAgICAgICB2YXIgdHJzdHIgPSAgJ3RyYW5zbGF0ZSgnK3gxKycsJyt5MSsnKSc7DQogICAgICAgIH1lbHNlew0KICAgICAgICAgICAgdmFyIHggPSBwYXJzZUZsb2F0KGNzWzBdKSsxNjsNCiAgICAgICAgICAgIHZhciB5ID0gcGFyc2VGbG9hdChjc1sxXSkrMTY7DQogICAgICAgICAgICB2YXIgeDEgPSB4ICogbWFBcnJbMF0gKyB5ICogbWFBcnJbMl0gKyBtYUFycls0XTsNCiAgICAgICAgICAgIHZhciB5MSA9IHggKiBtYUFyclsxXSArIHkgKiBtYUFyclszXSArIG1hQXJyWzVdOw0KICAgICAgICAgICAgeCA9IHBhcnNlRmxvYXQoY3NbMF0pKzE2Ow0KICAgICAgICAgICAgeSA9IHBhcnNlRmxvYXQoY3NbMV0pOw0KICAgICAgICAgICAgdmFyIHgyID0geCAqIG1hQXJyWzBdICsgeSAqIG1hQXJyWzJdICsgbWFBcnJbNF07DQogICAgICAgICAgICB2YXIgeTIgPSB4ICogbWFBcnJbMV0gKyB5ICogbWFBcnJbM10gKyBtYUFycls1XTsNCiAgICAgICAgICAgIHZhciBmeCA9IHgxPHgyP3gxLnRvc3VpdHN2ZygpOiB4Mi50b3N1aXRzdmcoKTsNCiAgICAgICAgICAgIHZhciBmeSA9IHkxPnkyP3kxLnRvc3VpdHN2ZygpOiB5Mi50b3N1aXRzdmcoKTsNCgkJCXZhciBvZmZ5ID0gTWF0aC5hYnMoeTEteTIpOwkJCQkJCQkJCQkgIA0KICAgICAgICAgICAgdmFyIHRyc3RyID0gICd0cmFuc2xhdGUoJytmeCsnLCcrZnkrJyknOw0KICAgICAgICAgICAgcG9wdXBSLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JyxvZmZ5LnRvU3RyaW5nKCkpOw0KICAgICAgICAgICAgcG9wdXBSLnNldEF0dHJpYnV0ZSgnd2lkdGgnLCcxNicpOw0KICAgICAgICAgICAgcG9wdXBSLnNldEF0dHJpYnV0ZSgneScsKC1vZmZ5KS50b1N0cmluZygpKTsNCiAgICAgICAgICAgIHBvcHVwUi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCd0cmFuc3BhcmVudCcpOw0KICAgICAgICAgICAgcG9wdXAuYXBwZW5kQ2hpbGQocG9wdXBSKTsNCiAgICAgICAgfQ0KICAgIH0NCiAgICB2YXIgYWw9YS5sZW5ndGg7DQogICAgZm9yKHZhciBqPTA7ajxhbDtqKyspew0KICAgICAgICBsaW5rYXJyLnB1c2goYVtqXS5saW5rKTsNCiAgICAgICAgZGVzY2Fyci5wdXNoKGFbal0uZGVzYyk7DQogICAgfQ0KICAgIHBvcHVwLnNldEF0dHJpYnV0ZSgndHJhbnNmb3JtJyx0cnN0cik7DQogICAgdmFyIG1heD1nZXRtYXhsZW4obGlua2FycixkZXNjYXJyKTsNCiAgICBmb3IodmFyIGs9MDtrPGFsO2srKyl7DQogICAgICAgIHZhciBjPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCdhJyk7DQogICAgICAgIHZhciBkPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCdyZWN0Jyk7DQogICAgICAgIHZhciBlPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCd0ZXh0Jyk7DQogICAgICAgIHZhciBmPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCd0ZXh0Jyk7DQogICAgICAgIGlmKGlzTmFOKGxpbmthcnJba10pKXsNCiAgICAgICAgICAgIGMuc2V0QXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiwgInhsaW5rIiwgImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiKTsNCiAgICAgICAgICAgIGMuc2V0QXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiLCAiaHJlZiIsIGxpbmthcnJba10pOw0KICAgICAgICAgICAgYy5zZXRBdHRyaWJ1dGUoJ3RhcmdldCcsJ19ibGFuaycpOw0KICAgICAgICAgICAgZS50ZXh0Q29udGVudD1saW5rYXJyW2tdOw0KICAgICAgICB9ZWxzZXsNCiAgICAgICAgICAgIGUudGV4dENvbnRlbnQ9J1BhZ2UtJytsaW5rYXJyW2tdOw0KICAgICAgICAgICAgYy5zZXRBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciLCAieGxpbmsiLCAiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIpOw0KICAgICAgICAgICAgYy5zZXRBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIsICJocmVmIiwgIiMiK2xpbmthcnJba10pOw0KICAgICAgICB9DQogICAgICAgIGQuc2V0QXR0cmlidXRlKCd3aWR0aCcsbWF4KzEwKTsNCiAgICAgICAgZC5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsJzMzJyk7DQogICAgICAgIGQuc2V0QXR0cmlidXRlKCdzdHJva2UnLCcjOTk5OTk5Jyk7DQogICAgICAgIGQuc2V0QXR0cmlidXRlKCdmaWxsJywnd2hpdGUnKTsNCiAgICAgICAgZC5zZXRBdHRyaWJ1dGUoJ3knLDMzKmspOw0KICAgICAgICBmLnRleHRDb250ZW50PWRlc2NhcnJba107DQogICAgICAgIGYuc3R5bGUuZm9udFNpemU9JzEycHgnOw0KICAgICAgICBmLnN0eWxlLmZvbnRXZWlnaHQ9J2JvbGQnOw0KICAgICAgICBmLnNldEF0dHJpYnV0ZSgneCcsNSk7DQogICAgICAgIGYuc2V0QXR0cmlidXRlKCd5JywzMyprKzEyKTsNCiAgICAgICAgZS5zdHlsZS5mb250U2l6ZT0nMTJweCc7DQogICAgICAgIGUuc2V0QXR0cmlidXRlKCd5JywzMyprKzI4KTsNCiAgICAgICAgZS5zZXRBdHRyaWJ1dGUoJ3gnLDUpOw0KICAgICAgICBjLmFwcGVuZENoaWxkKGQpOw0KICAgICAgICBjLmFwcGVuZENoaWxkKGYpOw0KICAgICAgICBjLmFwcGVuZENoaWxkKGUpOw0KICAgICAgICBjLm9ubW91c2VvdmVyPWZ1bmN0aW9uICgpIHsNCiAgICAgICAgICAgIHRoaXMucXVlcnlTZWxlY3RvcigncmVjdCcpLnN0eWxlLmZpbGw9JyNlMWUxZmYnDQogICAgICAgIH07DQogICAgICAgIGMub25tb3VzZW91dD1mdW5jdGlvbiAoKSB7DQogICAgICAgICAgICB0aGlzLnF1ZXJ5U2VsZWN0b3IoJ3JlY3QnKS5zdHlsZS5maWxsPSd3aGl0ZScNCiAgICAgICAgfTsNCiAgICAgICAgcG9wdXAuYXBwZW5kQ2hpbGQoYyk7DQogICAgfQ0KICAgIHBvcHVwLnN0eWxlLmRpc3BsYXk9J25vbmUnOw0KICAgIHBvcHVwLnNldEF0dHJpYnV0ZSgnaHlwZXJsaW5rJywnJyk7DQogICAgcG9wdXAuc2V0QXR0cmlidXRlKCdlZDpsaW5raWQnLGxpbmtzW2ldLnBhcmVudE5vZGUuaWQpOw0KICAgIHBvcHVwLm9ubW91c2VvdmVyPWZ1bmN0aW9uICgpIHsNCiAgICAgICAgdGhpcy5zdHlsZS5kaXNwbGF5PSdibG9jayc7DQogICAgfTsNCiAgICBwb3B1cC5vbmNsaWNrPWZ1bmN0aW9uICgpIHsNCiAgICAgICAgdGhpcy5zdHlsZS5kaXNwbGF5PSdub25lJzsNCiAgICB9Ow0KICAgIHBvcHVwLm9ubW91c2VvdXQ9ZnVuY3Rpb24gKCkgew0KICAgICAgICB0aGlzLnN0eWxlLmRpc3BsYXk9J25vbmUnOw0KICAgIH07DQogICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3N2Zy1jb250YWluZXIgPiBzdmcnKS5hcHBlbmRDaGlsZChwb3B1cCk7DQogICAgbGlua3NbaV0ub25tb3VzZW92ZXI9ZnVuY3Rpb24gKCkgew0KICAgICAgICB2YXIgbGlua2lkPXRoaXMucGFyZW50Tm9kZS5pZDsNCiAgICAgICAgdGhpcy5xdWVyeVNlbGVjdG9yKCdyZWN0Jykuc3R5bGUuZGlzcGxheT0nYmxvY2snOw0KICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCJnW2VkXFw6bGlua2lkPSciK2xpbmtpZCsiJ11baHlwZXJsaW5rXSIpLnN0eWxlLmRpc3BsYXk9J2Jsb2NrJzsNCiAgICB9DQogICAgbGlua3NbaV0ub25tb3VzZW91dD1mdW5jdGlvbiAoKSB7DQogICAgICAgIHZhciBsaW5raWQ9dGhpcy5wYXJlbnROb2RlLmlkOw0KICAgICAgICB0aGlzLnF1ZXJ5U2VsZWN0b3IoJ3JlY3QnKS5zdHlsZS5kaXNwbGF5PSdub25lJzsNCiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiZ1tlZFxcOmxpbmtpZD0nIitsaW5raWQrIiddW2h5cGVybGlua10iKS5zdHlsZS5kaXNwbGF5PSdub25lJzsNCiAgICB9DQp9DQovLy0taHlwZXJsaW5rDQovL2luaXRpYWxpemUtLQ0KdmFyIHNoYXBlPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2dbZWRcXDp0b2d0b3BpY2lkXScpOw0KdmFyIG1JZD1kb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdnW2VkXFw6dG9waWN0eXBlXScpOw0KdmFyIGRhdGFUcmVlPXt9Ow0KdmFyIGV4dHJhUmVsYT17fTsNCnZhciBjaGVja0lEPScnOw0KZm9yKHZhciBpPTA7aTxtSWQubGVuZ3RoO2krKyl7DQogICAgdmFyIHR5cGU9bUlkW2ldLmdldEF0dHJpYnV0ZSgnZWQ6dG9waWN0eXBlJyk7DQogICAgdmFyIHNpZD1tSWRbaV0uaWQ7DQogICAgaWYodHlwZSE9PSdjYWxsb3V0Jyl7DQogICAgICAgIGluaXQoc2lkLGRhdGFUcmVlKQ0KICAgIH0NCn0NCmZ1bmN0aW9uIGluaXQoaWQsIG9iaikgew0KICAgIHZhciBjaGlsZHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCJnW2VkXFw6cGFyZW50aWQ9JyIgKyBpZCArICInXTpub3QoW2VkXFw6dG9waWN0eXBlXSkiKTsNCiAgICB2YXIgY2FsbHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCJnW2VkXFw6cGFyZW50aWQ9JyIgKyBpZCArICInXVtlZFxcOnRvcGljdHlwZV0iKTsNCiAgICB2YXIgc3VtbWFyeSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoInBhdGhbZWRcXDpwYXJlbnRpZCo9JyIgKyBpZCArICInXVtlZFxcOnR5cGU9J3N1bW1hcnknXSIpOw0KICAgIHZhciBib3VuZGFyeT0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgicGF0aFtlZFxcOnBhcmVudGlkKj0nIiArIGlkICsgIiddW2VkXFw6dHlwZT0nYm91bmRhcnknXSIpOw0KICAgIHZhciByZWxhZnJvbT1kb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCJnW2VkXFw6ZnJvbWlkKj0nIiArIGlkICsgIiddW2VkXFw6dHlwZT0ncmVsYXRpb24nXSIpOw0KICAgIHZhciByZWxhdG89ZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgiZ1tlZFxcOnRvaWQqPSciICsgaWQgKyAiJ11bZWRcXDp0eXBlPSdyZWxhdGlvbiddIik7DQogICAgb2JqWyJtIiArIGlkXSA9IHt9Ow0KICAgIHZhciB0eXBlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpLmdldEF0dHJpYnV0ZSgnZWQ6dG9waWN0eXBlJyk7DQogICAgdmFyIGl3PWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKS5nZXRBdHRyaWJ1dGUoJ2VkOndpZHRoJyk7DQogICAgdmFyIGloPWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKS5nZXRBdHRyaWJ1dGUoJ2VkOmhlaWdodCcpOw0KICAgIGlmICh0eXBlKSB7DQogICAgICAgIG9ialsibSIgKyBpZF0udHlwZSA9IHR5cGU7DQogICAgfQ0KICAgIGlmKGl3JiZpaCl7DQogICAgICAgIG9ialsibSIgKyBpZF0ud2lkdGggPWl3Ow0KICAgICAgICBvYmpbIm0iICsgaWRdLmhlaWdodCA9aWg7DQogICAgfQ0KICAgIGlmIChyZWxhZnJvbS5sZW5ndGggIT09IDApIHsNCiAgICAgICAgb2JqWyJtIiArIGlkXS5yZWxhZnJvbSA9IHt9Ow0KICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlbGFmcm9tLmxlbmd0aDsgaSsrKSB7DQogICAgICAgICAgICB2YXIgaW5kZXhpZCA9IHJlbGFmcm9tW2ldLmlkOw0KICAgICAgICAgICAgdmFyIHRvaWQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpbmRleGlkKS5nZXRBdHRyaWJ1dGUoJ2VkOnRvaWQnKTsNCiAgICAgICAgICAgIGlmIChleHRyYVJlbGFbaW5kZXhpZF0gPT09IHVuZGVmaW5lZCkgew0KICAgICAgICAgICAgICAgIGV4dHJhUmVsYVtpbmRleGlkXSA9IHsNCiAgICAgICAgICAgICAgICAgICAgaWQ6IGluZGV4aWQsDQogICAgICAgICAgICAgICAgICAgIGZyb21pZDogaWQsDQogICAgICAgICAgICAgICAgICAgIHRvaWQ6IHRvaWQsDQogICAgICAgICAgICAgICAgICAgIGlzQzogZmFsc2UNCiAgICAgICAgICAgICAgICB9Ow0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgb2JqWyJtIiArIGlkXS5yZWxhZnJvbVtpbmRleGlkXT17fTsNCiAgICAgICAgICAgIG9ialsibSIgKyBpZF0ucmVsYWZyb20uZGlzcGxheT1kb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkuc3R5bGUuZGlzcGxheSAhPT0gJ25vbmUnPydibG9jayc6J25vbmUnOw0KICAgICAgICB9DQogICAgfQ0KICAgIGlmIChyZWxhdG8ubGVuZ3RoICE9PSAwKSB7DQogICAgICAgIG9ialsibSIgKyBpZF0ucmVsYXRvID0ge307DQogICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVsYXRvLmxlbmd0aDsgaSsrKSB7DQogICAgICAgICAgICB2YXIgaW5kZXhpZD1yZWxhdG9baV0uaWQ7DQogICAgICAgICAgICB2YXIgZnJvbWlkPWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGluZGV4aWQpLmdldEF0dHJpYnV0ZSgnZWQ6ZnJvbWlkJyk7DQogICAgICAgICAgICBpZihleHRyYVJlbGFbaW5kZXhpZF0gPT09IHVuZGVmaW5lZCl7DQogICAgICAgICAgICAgICAgZXh0cmFSZWxhW2luZGV4aWRdPXsNCiAgICAgICAgICAgICAgICAgICAgaWQ6aW5kZXhpZCwNCiAgICAgICAgICAgICAgICAgICAgZnJvbWlkOmZyb21pZCwNCiAgICAgICAgICAgICAgICAgICAgdG9pZDppZCwNCiAgICAgICAgICAgICAgICAgICAgaXNDOmZhbHNlDQogICAgICAgICAgICAgICAgfTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIG9ialsibSIgKyBpZF0ucmVsYXRvW2luZGV4aWRdPXt9Ow0KICAgICAgICAgICAgb2JqWyJtIiArIGlkXS5yZWxhdG8uZGlzcGxheT1kb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkuc3R5bGUuZGlzcGxheSAhPT0gJ25vbmUnPydibG9jayc6J25vbmUnOw0KICAgICAgICB9DQogICAgfQ0KICAgIGlmIChjaGlsZHMubGVuZ3RoICE9PSAwKSB7DQogICAgICAgIG9ialsibSIgKyBpZF0uY2hpbGQgPSB7fTsNCiAgICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoImdbZWRcXDp0b2d0b3BpY2lkPSciICsgaWQgKyAiJ10iKSkgew0KICAgICAgICAgICAgLy8gY29uc29sZS5sb2coZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiZ1tlZFxcOnRvZ3RvcGljaWQ9JyIgKyBpZCArICInXSIpLmNoaWxkTm9kZXNbMF0uZ2V0QXR0cmlidXRlKCd4bGluazpocmVmJykpOw0KICAgICAgICAgICAgdmFyIHRvZyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoImdbZWRcXDp0b2d0b3BpY2lkPSciICsgaWQgKyAiJ10iKS5nZXRFbGVtZW50c0J5VGFnTmFtZSgndXNlJylbMF0uZ2V0QXR0cmlidXRlKCd4bGluazpocmVmJykuc2xpY2UoMSk7DQogICAgICAgICAgICBvYmpbIm0iICsgaWRdLnRvZ3R5cGUgPSB0b2c7DQogICAgICAgIH0NCiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaGlsZHMubGVuZ3RoOyBpKyspIHsNCiAgICAgICAgICAgIHZhciBjaWQgPSBjaGlsZHNbaV0uaWQ7DQogICAgICAgICAgICBpbml0KGNpZCwgb2JqWyJtIiArIGlkXS5jaGlsZCk7DQogICAgICAgIH0NCiAgICB9DQogICAgaWYgKGNhbGxzLmxlbmd0aCAhPT0gMCkgew0KICAgICAgICBvYmpbIm0iICsgaWRdLmNhbGwgPSB7fTsNCiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjYWxscy5sZW5ndGg7IGkrKykgew0KICAgICAgICAgICAgdmFyIGNpZCA9IGNhbGxzW2ldLmlkOw0KICAgICAgICAgICAgaW5pdChjaWQsIG9ialsibSIgKyBpZF0uY2FsbCk7DQogICAgICAgIH0NCiAgICB9DQogICAgaWYgKGJvdW5kYXJ5Lmxlbmd0aCAhPT0gMCkgew0KICAgICAgICBvYmpbIm0iICsgaWRdLmJvdW5kYXJ5ID0ge307DQogICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYm91bmRhcnkubGVuZ3RoOyBpKyspIHsNCiAgICAgICAgICAgIHZhciBjaWQgPWJvdW5kYXJ5W2ldLmlkOw0KICAgICAgICAgICAgaW5pdChjaWQsIG9ialsibSIgKyBpZF0uYm91bmRhcnkpOw0KICAgICAgICB9DQogICAgfQ0KICAgIGlmIChzdW1tYXJ5Lmxlbmd0aCAhPT0gMCkgew0KICAgICAgICBvYmpbIm0iICsgaWRdLnN1bW1hcnkgPSB7fTsNCiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdW1tYXJ5Lmxlbmd0aDsgaSsrKSB7DQogICAgICAgICAgICB2YXIgY2lkID0gc3VtbWFyeVtpXS5pZDsNCiAgICAgICAgICAgIGluaXQoY2lkLCBvYmpbIm0iICsgaWRdLnN1bW1hcnkpOw0KICAgICAgICB9DQogICAgfQ0KfQ0KLy8tLWluaXRpYWxpemUNCi8vdG9nZ2xlZGlzcGxheS0tDQp2YXIgY2hhaW5BcnI9W107DQpmdW5jdGlvbiBnZXRjaGFpbihpZCl7DQogICAgY2hhaW5BcnIudW5zaGlmdCgnbScraWQpOw0KICAgIHZhciBwYXJlbnQ9ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpLmdldEF0dHJpYnV0ZSgnZWQ6cGFyZW50aWQnKTsNCiAgICBpZighcGFyZW50KXsNCiAgICAgICAgcmV0dXJuOw0KICAgIH0NCglpZihwYXJlbnQubWF0Y2goL1wsLykpew0KICAgICAgICBwYXJlbnQgPSBwYXJlbnQubWF0Y2goL1xkKyg/PVwsKS8pWzBdDQogICAgfQ0KICAgIGdldGNoYWluKHBhcmVudCk7DQp9DQpmdW5jdGlvbiBnZXRvYmooaWQpIHsNCiAgICBjaGFpbkFycj1bXTsNCiAgICBnZXRjaGFpbihpZCk7DQogICAgdmFyIG1haW49Y2hhaW5BcnJbMF07DQogICAgaWYoY2hhaW5BcnIubGVuZ3RoPjEpew0KICAgICAgICB2YXIgb2JqPWRhdGFUcmVlW21haW5dOw0KICAgICAgICAvLyBjb25zb2xlLmxvZyhjaGFpbkFycik7DQogICAgICAgIGZvcih2YXIgaT0xO2k8Y2hhaW5BcnIubGVuZ3RoO2krKykgew0KICAgICAgICAgICAgdmFyIGEgPSBjaGFpbkFycltpXTsNCiAgICAgICAgICAgIGZvcih2YXIgaj0wO2o8T2JqZWN0LmtleXMob2JqKS5sZW5ndGg7aisrKXsNCiAgICAgICAgICAgICAgICB2YXIgY29iaj0gb2JqW09iamVjdC5rZXlzKG9iailbal1dW2FdOw0KICAgICAgICAgICAgICAgIGlmKGNvYmopew0KICAgICAgICAgICAgICAgICAgICBvYmo9Y29iajsNCiAgICAgICAgICAgICAgICAgICAgY29udGludWUNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgcmV0dXJuIG9iag0KICAgIH1lbHNlew0KICAgICAgICB2YXIgb2JqPWRhdGFUcmVlW21haW5dOw0KICAgICAgICByZXR1cm4gb2JqDQogICAgfQ0KDQp9DQpmb3IodmFyIGk9MDtpPHNoYXBlLmxlbmd0aDtpKyspew0KICAgIHNoYXBlW2ldLm9uY2xpY2s9ZnVuY3Rpb24gKCkgew0KICAgICAgICB2YXIgaWQ9TnVtYmVyKHRoaXMuZ2V0QXR0cmlidXRlKCdlZDp0b2d0b3BpY2lkJykpOw0KICAgICAgICB2YXIgb2JqPWdldG9iaihpZCk7DQoNCiAgICAgICAgdmFyIHR5cGU9b2JqLnRvZ3R5cGU9PT0nbWludXMnPydwbHVzJzonbWludXMnOw0KICAgICAgICB2YXIgZGlzcGxheT1vYmoudG9ndHlwZT09PSdtaW51cyc/J25vbmUnOidibG9jayc7DQogICAgICAgIHRoaXMuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ3VzZScpWzBdLnNldEF0dHJpYnV0ZSgneGxpbms6aHJlZicsJyMnK3R5cGUpOw0KICAgICAgICBvYmoudG9ndHlwZT10eXBlOw0KICAgICAgICBjaGVja0lEPW9iajsNCg0KICAgICAgICB1dGQob2JqLGlkLGRpc3BsYXkpOw0KICAgICAgICBleHRyYVJlbGFGaW4oKTsNCiAgICB9DQp9DQpmdW5jdGlvbiB1dGQob2JqLGlkLHNob3csb2MpIHsNCg0KICAgIHZhciBwc2hvdz1kb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkuc3R5bGUuZGlzcGxheSE9PSAnbm9uZSc/J2Jsb2NrJzonbm9uZSc7DQogICAgaWYgKG9iai5yZWxhZnJvbSl7DQogICAgICAgIGlmKG9iai5yZWxhZnJvbS5kaXNwbGF5IT09IHBzaG93KXsNCiAgICAgICAgICAgIHZhciByZWxhZnJvbXM9T2JqZWN0LmtleXMob2JqLnJlbGFmcm9tKTsNCiAgICAgICAgICAgIHJlbGFmcm9tcy5zcGxpY2UocmVsYWZyb21zLmluZGV4T2YoJ2Rpc3BsYXknKSwxKTsNCiAgICAgICAgICAgIGZvcih2YXIgaz0wO2s8cmVsYWZyb21zLmxlbmd0aDtrKyspew0KICAgICAgICAgICAgICAgIHZhciBkPXJlbGFmcm9tc1trXTsNCiAgICAgICAgICAgICAgICBleHRyYVJlbGFbZF0uaXNDPXRydWU7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBvYmoucmVsYWZyb20uZGlzcGxheSA9IHBzaG93Ow0KICAgICAgICB9DQogICAgfQ0KICAgIGlmIChvYmoucmVsYXRvKXsNCiAgICAgICAgaWYob2JqLnJlbGF0by5kaXNwbGF5IT09IHBzaG93KXsNCiAgICAgICAgICAgIHZhciByZWxhdG9zPU9iamVjdC5rZXlzKG9iai5yZWxhdG8pOw0KICAgICAgICAgICAgcmVsYXRvcy5zcGxpY2UocmVsYXRvcy5pbmRleE9mKCdkaXNwbGF5JyksMSk7DQogICAgICAgICAgICBmb3IodmFyIGs9MDtrPHJlbGF0b3MubGVuZ3RoO2srKyl7DQogICAgICAgICAgICAgICAgdmFyIGQ9cmVsYXRvc1trXTsNCiAgICAgICAgICAgICAgICBleHRyYVJlbGFbZF0uaXNDPXRydWU7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBvYmoucmVsYXRvLmRpc3BsYXkgPSBwc2hvdzsNCiAgICAgICAgfQ0KICAgIH0NCiAgICBpZihvYmouY2FsbCl7DQogICAgICAgIHZhciBjYWxscz1PYmplY3Qua2V5cyhvYmouY2FsbCk7DQogICAgICAgIGlmKGNoZWNrSUQhPT1vYmopew0KICAgICAgICAgICAgZm9yKHZhciBpPTA7aSA8IGNhbGxzLmxlbmd0aDtpKyspew0KICAgICAgICAgICAgICAgIHZhciBhPWNhbGxzW2ldLnNsaWNlKDEpOw0KICAgICAgICAgICAgICAgIHZhciBiPW9iai5jYWxsW2NhbGxzW2ldXTsNCiAgICAgICAgICAgICAgICB2YXIgYz1iLnRvZ3R5cGU7DQogICAgICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYSkuc3R5bGUuZGlzcGxheT1zaG93Ow0KICAgICAgICAgICAgICAgIGlmIChiLnJlbGFmcm9tJiYhYyl7DQogICAgICAgICAgICAgICAgICAgIGlmKGIucmVsYWZyb20uZGlzcGxheSE9PSBzaG93KXsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZWxhZnJvbXM9T2JqZWN0LmtleXMoYi5yZWxhZnJvbSk7DQogICAgICAgICAgICAgICAgICAgICAgICByZWxhZnJvbXMuc3BsaWNlKHJlbGFmcm9tcy5pbmRleE9mKCdkaXNwbGF5JyksMSk7DQogICAgICAgICAgICAgICAgICAgICAgICBmb3IodmFyIGs9MDtrPHJlbGFmcm9tcy5sZW5ndGg7aysrKXsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZD1yZWxhZnJvbXNba107DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0cmFSZWxhW2RdLmlzQz10cnVlOw0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgYi5yZWxhZnJvbS5kaXNwbGF5ID0gc2hvdzsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICBpZiAoYi5yZWxhdG8mJiFjKXsNCiAgICAgICAgICAgICAgICAgICAgaWYoYi5yZWxhdG8uZGlzcGxheSE9PSBzaG93KXsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZWxhdG9zPU9iamVjdC5rZXlzKGIucmVsYXRvKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIHJlbGF0b3Muc3BsaWNlKHJlbGF0b3MuaW5kZXhPZignZGlzcGxheScpLDEpOw0KICAgICAgICAgICAgICAgICAgICAgICAgZm9yKHZhciBrPTA7azxyZWxhdG9zLmxlbmd0aDtrKyspew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkPXJlbGF0b3Nba107DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0cmFSZWxhW2RdLmlzQz10cnVlOw0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgYi5yZWxhdG8uZGlzcGxheSA9IHNob3c7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgaWYoYyl7DQogICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoImdbZWRcXDp0b2d0b3BpY2lkPSciK2ErIiddIikuc3R5bGUuZGlzcGxheT1zaG93Ow0KICAgICAgICAgICAgICAgICAgICBpZihjPT09J21pbnVzJyl7DQogICAgICAgICAgICAgICAgICAgICAgICB1dGQoYixhLHNob3cpDQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgaWYgKChiLmNhbGx8fGIuYm91bmRhcnl8fGIuc3VtbWFyeSkmJmM9PT0ncGx1cycpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHV0ZChiLGEsc2hvdyx0cnVlKQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGlmKGIuY2FsbCYmIWMpIHsNCiAgICAgICAgICAgICAgICAgICAgdXRkKGIsYSxzaG93LHRydWUpDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGlmIChiLnN1bW1hcnkmJiFjKSB7DQogICAgICAgICAgICAgICAgICAgIHV0ZChiLGEsc2hvdykNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgaWYgKGIuYm91bmRhcnkmJiFjKSB7DQogICAgICAgICAgICAgICAgICAgIHV0ZChiLGEsc2hvdykNCiAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgIH0NCiAgICBpZihvYmouc3VtbWFyeSl7DQogICAgICAgIHZhciBzdW1tYXJ5cz1PYmplY3Qua2V5cyhvYmouc3VtbWFyeSk7DQogICAgICAgIGlmKChjaGVja0lEIT09b2JqJiYob2JqLnRvZ3R5cGU9PT0nbWludXMnfHwhb2JqLnRvZ3R5cGUpKXx8Y2hlY2tJRD09PW9iail7DQogICAgICAgICAgICBmb3IodmFyIGk9MDtpPHN1bW1hcnlzLmxlbmd0aDtpKyspew0KICAgICAgICAgICAgICAgIHZhciBhPXN1bW1hcnlzW2ldLnNsaWNlKDEpOw0KCQkJCXZhciBvc3AgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChhKS5nZXRBdHRyaWJ1dGUoJ2VkOnBhcmVudGlkJyk7DQogICAgICAgICAgICAgICAgaWYob3NwLm1hdGNoKC9cLC8pKXsNCiAgICAgICAgICAgICAgICAgICAgdmFyIG9zcGEgPSBvc3Auc3BsaXQoJywnKTsNCiAgICAgICAgICAgICAgICAgICAgdmFyIG9zcEw9MDsNCg0KICAgICAgICAgICAgICAgICAgICBmb3IodmFyIGo9MDtqPG9zcGEubGVuZ3RoO2orKyl7DQogICAgICAgICAgICAgICAgICAgICAgICBpZihzaG93ID09ICdub25lJyl7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQob3NwYVtqXSkuc3R5bGUuZGlzcGxheSAhPSAnbm9uZScpew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9ZWxzZXsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3NwTCsrOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIH1lbHNlew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihkb2N1bWVudC5nZXRFbGVtZW50QnlJZChhKS5zdHlsZS5kaXNwbGF5ICE9ICdub25lJyl7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfWVsc2V7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvc3BMKys7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIGlmKG9zcEwgIT09IG9zcGEubGVuZ3RoKXsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIHZhciBiPW9iai5zdW1tYXJ5W3N1bW1hcnlzW2ldXTsNCiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhhKTsNCiAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChhKS5zdHlsZS5kaXNwbGF5PXNob3c7DQovLyAgICAgICAgICAgICAgICBpZihjKXsNCi8vICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCJnW2VkXFw6dG9ndG9waWNpZD0nIithKyInXSIpLnN0eWxlLmRpc3BsYXk9c2hvdzsNCi8vICAgICAgICAgICAgICAgICAgICBpZihjPT09J21pbnVzJyl7DQovLyAgICAgICAgICAgICAgICAgICAgICAgIHV0ZChiLHNob3cpDQovLyAgICAgICAgICAgICAgICAgICAgfQ0KLy8gICAgICAgICAgICAgICAgICAgIGlmIChiLmNhbGwmJmM9PT0ncGx1cycpIHsNCi8vICAgICAgICAgICAgICAgICAgICAgICAgdXRkKGIsc2hvdyx0cnVlKQ0KLy8gICAgICAgICAgICAgICAgICAgIH0NCi8vICAgICAgICAgICAgICAgIH0NCi8vICAgICAgICAgICAgICAgIGlmKGIuY2FsbCYmIWMpIHsNCi8vICAgICAgICAgICAgICAgICAgICB1dGQoYixzaG93LHRydWUpDQovLyAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgaWYoT2JqZWN0LmtleXMoYikubGVuZ3RoIT09MCl7DQogICAgICAgICAgICAgICAgICAgIHV0ZChiLGEsc2hvdykNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICB9DQogICAgaWYob2JqLmJvdW5kYXJ5KXsNCiAgICAgICAgdmFyIGJvdW5kYXJ5cz1PYmplY3Qua2V5cyhvYmouYm91bmRhcnkpOw0KICAgICAgICBpZihjaGVja0lEIT09b2JqKXsNCiAgICAgICAgICAgIGZvcih2YXIgaT0wO2k8Ym91bmRhcnlzLmxlbmd0aDtpKyspew0KICAgICAgICAgICAgICAgIHZhciBhPWJvdW5kYXJ5c1tpXS5zbGljZSgxKTsNCiAgICAgICAgICAgICAgICB2YXIgYj1vYmouYm91bmRhcnlbYm91bmRhcnlzW2ldXTsNCiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhhKTsNCiAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChhKS5zdHlsZS5kaXNwbGF5PXNob3c7DQovLyAgICAgICAgICAgICAgICBpZihjKXsNCi8vICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCJnW2VkXFw6dG9ndG9waWNpZD0nIithKyInXSIpLnN0eWxlLmRpc3BsYXk9c2hvdzsNCi8vICAgICAgICAgICAgICAgICAgICBpZihjPT09J21pbnVzJyl7DQovLyAgICAgICAgICAgICAgICAgICAgICAgIHV0ZChiLHNob3cpDQovLyAgICAgICAgICAgICAgICAgICAgfQ0KLy8gICAgICAgICAgICAgICAgICAgIGlmIChiLmNhbGwmJmM9PT0ncGx1cycpIHsNCi8vICAgICAgICAgICAgICAgICAgICAgICAgdXRkKGIsc2hvdyx0cnVlKQ0KLy8gICAgICAgICAgICAgICAgICAgIH0NCi8vICAgICAgICAgICAgICAgIH0NCi8vICAgICAgICAgICAgICAgIGlmKGIuY2FsbCYmIWMpIHsNCi8vICAgICAgICAgICAgICAgICAgICB1dGQoYixzaG93LHRydWUpDQovLyAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgaWYoT2JqZWN0LmtleXMoYikubGVuZ3RoIT09MCl7DQogICAgICAgICAgICAgICAgICAgIHV0ZChiLGEsc2hvdykNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICB9DQogICAgaWYoIW9jJiZvYmouY2hpbGQpIHsNCiAgICAgICAgdmFyIGNoaWxkcyA9IE9iamVjdC5rZXlzKG9iai5jaGlsZCk7DQogICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGRzLmxlbmd0aDsgaSsrKSB7DQogICAgICAgICAgICB2YXIgYSA9IGNoaWxkc1tpXS5zbGljZSgxKTsNCiAgICAgICAgICAgIHZhciBiID0gb2JqLmNoaWxkW2NoaWxkc1tpXV07DQogICAgICAgICAgICB2YXIgYyA9IGIudG9ndHlwZTsNCiAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGEpLnN0eWxlLmRpc3BsYXkgPSBzaG93Ow0KCQkJdmFyIHRTUGF0aCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoInBhdGhbZWRcXDp0b3N1cGVyaWQ9JyIrYSsiJ10iKTsNCiAgICAgICAgICAgIGlmKHRTUGF0aCl7DQogICAgICAgICAgICAgICAgdFNQYXRoLnN0eWxlLmRpc3BsYXkgPSBzaG93Ow0KICAgICAgICAgICAgfQ0KCQkJdmFyIG5vdGVUaXAgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCJnW2VkXFw6bm90ZXRvPSciK2ErIiddIik7DQogICAgICAgICAgICBpZihub3RlVGlwKXsNCiAgICAgICAgICAgICAgICBub3RlVGlwLnN0eWxlLmRpc3BsYXkgPSBzaG93Ow0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgaWYgKGIucmVsYWZyb20mJiFjKXsNCiAgICAgICAgICAgICAgICBpZihiLnJlbGFmcm9tLmRpc3BsYXkhPT0gc2hvdyl7DQogICAgICAgICAgICAgICAgICAgIHZhciByZWxhZnJvbXM9T2JqZWN0LmtleXMoYi5yZWxhZnJvbSk7DQogICAgICAgICAgICAgICAgICAgIHJlbGFmcm9tcy5zcGxpY2UocmVsYWZyb21zLmluZGV4T2YoJ2Rpc3BsYXknKSwxKTsNCiAgICAgICAgICAgICAgICAgICAgZm9yKHZhciBrPTA7azxyZWxhZnJvbXMubGVuZ3RoO2srKyl7DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZD1yZWxhZnJvbXNba107DQogICAgICAgICAgICAgICAgICAgICAgICBleHRyYVJlbGFbZF0uaXNDPXRydWU7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgYi5yZWxhZnJvbS5kaXNwbGF5ID0gc2hvdzsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICBpZiAoYi5yZWxhdG8mJiFjKXsNCiAgICAgICAgICAgICAgICBpZihiLnJlbGF0by5kaXNwbGF5IT09IHNob3cpew0KICAgICAgICAgICAgICAgICAgICB2YXIgcmVsYXRvcz1PYmplY3Qua2V5cyhiLnJlbGF0byk7DQogICAgICAgICAgICAgICAgICAgIHJlbGF0b3Muc3BsaWNlKHJlbGF0b3MuaW5kZXhPZignZGlzcGxheScpLDEpOw0KICAgICAgICAgICAgICAgICAgICBmb3IodmFyIGs9MDtrPHJlbGF0b3MubGVuZ3RoO2srKyl7DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZD1yZWxhdG9zW2tdOw0KICAgICAgICAgICAgICAgICAgICAgICAgZXh0cmFSZWxhW2RdLmlzQz10cnVlOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIGIucmVsYXRvLmRpc3BsYXkgPSBzaG93Ow0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGlmIChjKSB7DQogICAgICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiZ1tlZFxcOnRvZ3RvcGljaWQ9JyIgKyBhICsgIiddIikuc3R5bGUuZGlzcGxheSA9IHNob3c7DQogICAgICAgICAgICAgICAgaWYgKGMgPT09ICdtaW51cycpIHsNCiAgICAgICAgICAgICAgICAgICAgdXRkKGIsYSxzaG93KQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICBpZiAoKGIuY2FsbHx8Yi5ib3VuZGFyeXx8Yi5zdW1tYXJ5KSYmYz09PSdwbHVzJykgew0KICAgICAgICAgICAgICAgICAgICB1dGQoYixhLHNob3csdHJ1ZSkNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICBpZiAoYi5jYWxsJiYhYykgew0KICAgICAgICAgICAgICAgIHV0ZChiLGEsc2hvdyx0cnVlKQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgaWYgKGIuc3VtbWFyeSYmIWMpIHsNCiAgICAgICAgICAgICAgICB1dGQoYixhLHNob3cpDQogICAgICAgICAgICB9DQogICAgICAgICAgICBpZiAoYi5ib3VuZGFyeSYmIWMpIHsNCiAgICAgICAgICAgICAgICB1dGQoYixhLHNob3cpDQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICB9DQp9DQoNCmZ1bmN0aW9uIGV4dHJhUmVsYUZpbigpIHsNCiAgICB2YXIgZXh0cmFrZXlzPU9iamVjdC5rZXlzKGV4dHJhUmVsYSk7DQogICAgZm9yKHZhciBpPTA7aTxleHRyYWtleXMubGVuZ3RoO2krKyl7DQogICAgICAgIHZhciBleHRyYU9iaj1leHRyYVJlbGFbZXh0cmFrZXlzW2ldXTsNCiAgICAgICAgaWYoZXh0cmFPYmouaXNDID09PSB0cnVlKXsNCiAgICAgICAgICAgIHZhciBmc2hvdz1kb2N1bWVudC5nZXRFbGVtZW50QnlJZChleHRyYU9iai5mcm9taWQpLnN0eWxlLmRpc3BsYXkgIT09J25vbmUnPyB0cnVlOiBmYWxzZTsNCiAgICAgICAgICAgIHZhciB0c2hvdz1kb2N1bWVudC5nZXRFbGVtZW50QnlJZChleHRyYU9iai50b2lkKS5zdHlsZS5kaXNwbGF5ICE9PSdub25lJz8gdHJ1ZTogZmFsc2U7DQogICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChleHRyYU9iai5pZCkuc3R5bGUuZGlzcGxheT1mc2hvdyAmJiB0c2hvdz8gJ2Jsb2NrJzogJ25vbmUnOw0KICAgICAgICAgICAgZXh0cmFSZWxhW2V4dHJha2V5c1tpXV0uaXNDID0gZmFsc2U7DQogICAgICAgIH0NCiAgICB9DQp9'))</script>
  </body>
</html>
